Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- function str_replace_once($needle, $haystack, $replace) {
- $pos = strpos ( $haystack, $needle );
- if ($pos !== false) {
- $haystack = substr_replace ( $haystack, $replace, $pos, strlen ( $needle ) );
- }
- return $haystack;
- }
- class SentencialForm {
- public function __construct($rules, $beginNeterm, $prevRule, $seekSentence, $step = 0, $parent = null) {
- $this->form = $beginNeterm;
- $this->prevRule = $prevRule;
- $this->rules = $rules;
- $this->seekSentence = $seekSentence;
- $this->seekSentenceLength = strlen ( $seekSentence ) + 3;
- $this->step = $step;
- $this->parent = $parent;
- }
- public function isApplicable() {
- if (strlen ( $this->form ) > $this->seekSentenceLength) {
- return false;
- }
- $lSideContained = strpos ( $this->form, $this->prevRule->lSide ) !== false;
- // $allowed = in_array ( $rule, $this->prevRule->allow );
- // $denied = in_array ( $rule, $this->prevRule->deny );
- $allowed = true;
- $denied = true;
- if ($lSideContained && $allowed) {
- $data = array ();
- foreach ( $this->prevRule->allow as $nextRule ) {
- $data [] = new SentencialForm ( $this->rules, str_replace_once ( $this->prevRule->lSide, $this->form, $this->prevRule->rSide ), $nextRule, $this->seekSentence, $this->step + 1, $this );
- }
- return $data;
- } else if (! $lSideContained && $denied) {
- $data = array ();
- foreach ( $this->prevRule->deny as $nextRule ) {
- $data [] = new SentencialForm ( $this->rules, $this->form, $nextRule, $this->seekSentence, $this->step + 1, $this );
- }
- return $data;
- } else {
- return false;
- }
- }
- public function isDone() {
- return $this->form == $this->seekSentence;
- }
- public function getTrace() {
- $trace = array ();
- $parent = $this;
- while ( $parent != null ) {
- $trace [] = $parent;
- $parent = $parent->parent;
- }
- return array_reverse ( $trace );
- }
- public function toString() {
- return "[" . $this->step . "](" . $this->form . "," . $this->prevRule->index . ")";
- }
- public function printTrace() {
- $trace = $this->getTrace ();
- foreach ( $trace as $sentence ) {
- echo $sentence->toString () . "\r\n";
- }
- }
- }
- class Rule {
- public function __construct($index, $lSide, $rSide, $allow, $deny) {
- $this->index = $index;
- $this->lSide = $lSide;
- $this->rSide = $rSide;
- $this->allow = $allow;
- $this->deny = $deny;
- }
- }
- class Rules {
- public function __construct($ruleStr) {
- $rs = explode ( "\n", trim ( $ruleStr ) );
- $this->rules = array_map ( function ($x) {
- $toInt = function ($x) {
- return $x * 1;
- };
- $x = explode ( ":", trim ( $x ), 2 );
- $num = $toInt ( $x [0] );
- $x = explode ( "->", $x [1], 2 );
- $lSide = $x [0];
- $x = explode ( "(", $x [1], 2 );
- $rSide = $x [0];
- $x = explode ( ")", $x [1], 2 );
- $allow = $x [0] == "" ? array () : array_map ( $toInt, explode ( ",", $x [0] ) );
- $x = explode ( ",(", $x [1], 2 );
- $x = explode ( ")", $x [1], 2 );
- $deny = $x [0] == "" ? array () : array_map ( $toInt, explode ( ",", $x [0] ) );
- return new Rule ( $num, $lSide, $rSide, $allow, $deny );
- }, $rs );
- $getR = function ($rules, $index) {
- foreach ( $rules as $rule ) {
- if ($rule->index == $index) {
- return $rule;
- }
- }
- return false;
- };
- foreach ( $this->rules as $rule ) {
- $dataAllow = array ();
- foreach ( $rule->allow as $allowI ) {
- $x = $getR ( $this->rules, $allowI );
- if ($x === false) {
- die ( "Invalid allow rule: " . $allowI );
- }
- $dataAllow [] = $x;
- }
- $dataDeny = array ();
- foreach ( $rule->deny as $deniedI ) {
- $x = $getR ( $this->rules, $deniedI );
- if ($x === false) {
- die ( "Invalid deny rule: " . $deniedI );
- }
- $dataDeny [] = $x;
- }
- $rule->allow = $dataAllow;
- $rule->deny = $dataDeny;
- }
- }
- }
- function parse($sentenceI, $printFailed, $printGood, $printResultInfo) {
- $ruleStr = "1:S->SC(1,2),()
- 2:S->AA(3),()
- 3:A->B(4),(5)
- 4:C->D(3),(7)
- 5:C->C(6),()
- 6:B->A(6),(3)
- 7:B->A(7),(8)
- 8:D->A(9),(10)
- 9:D->C(9),(3)
- 10:A->a(10),()";
- $rules = new Rules ( $ruleStr );
- $sentence = new SentencialForm ( $rules->rules, "S", $rules->rules [0], $sentenceI );
- $stack = array (
- $sentence
- );
- while ( count ( $stack ) > 0 ) {
- $sentence = array_shift ( $stack );
- if ($sentence->isDone ()) {
- if ($printGood) {
- echo "\r\n";
- echo "Finished:\r\n";
- $sentence->printTrace ();
- }
- if ($printResultInfo) {
- echo "Accepted sentence " . $sentenceI . "\r\n";
- }
- return true;
- }
- $expanded = false;
- $nextSentences = $sentence->isApplicable ();
- if ($nextSentences !== false) {
- foreach ( $nextSentences as $nextSentence ) {
- $stack [] = $nextSentence;
- $expanded = true;
- }
- }
- if (! $expanded) {
- if ($printFailed) {
- echo "\r\n";
- echo "Failed:\r\n";
- $sentence->printTrace ();
- echo "\r\n";
- }
- }
- }
- if ($printResultInfo) {
- echo "Rejected sentence " . $sentenceI . "\r\n";
- }
- return false;
- }
- $s = "a";
- for($i = 0; $i < 100; $i ++) {
- if (parse ( $s, false, false, false )) {
- echo "Accepted: " . strlen ( $s ) . "\r\n";
- }
- $s .= "a";
- }
- //parse ( "aaa", false, false, true );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement