Advertisement
Tarferi

RGD Prime Grammar

Jan 12th, 2020
430
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 5.17 KB | None | 0 0
  1. <?php
  2.  
  3. function str_replace_once($needle, $haystack, $replace) {
  4.     $pos = strpos ( $haystack, $needle );
  5.     if ($pos !== false) {
  6.         $haystack = substr_replace ( $haystack, $replace, $pos, strlen ( $needle ) );
  7.     }
  8.     return $haystack;
  9. }
  10.  
  11. class SentencialForm {
  12.  
  13.     public function __construct($rules, $beginNeterm, $prevRule, $seekSentence, $step = 0, $parent = null) {
  14.         $this->form = $beginNeterm;
  15.         $this->prevRule = $prevRule;
  16.         $this->rules = $rules;
  17.         $this->seekSentence = $seekSentence;
  18.         $this->seekSentenceLength = strlen ( $seekSentence ) + 3;
  19.         $this->step = $step;
  20.         $this->parent = $parent;
  21.     }
  22.  
  23.     public function isApplicable() {
  24.         if (strlen ( $this->form ) > $this->seekSentenceLength) {
  25.             return false;
  26.         }
  27.         $lSideContained = strpos ( $this->form, $this->prevRule->lSide ) !== false;
  28.         // $allowed = in_array ( $rule, $this->prevRule->allow );
  29.         // $denied = in_array ( $rule, $this->prevRule->deny );
  30.         $allowed = true;
  31.         $denied = true;
  32.         if ($lSideContained && $allowed) {
  33.             $data = array ();
  34.             foreach ( $this->prevRule->allow as $nextRule ) {
  35.                 $data [] = new SentencialForm ( $this->rules, str_replace_once ( $this->prevRule->lSide, $this->form, $this->prevRule->rSide ), $nextRule, $this->seekSentence, $this->step + 1, $this );
  36.             }
  37.             return $data;
  38.         } else if (! $lSideContained && $denied) {
  39.             $data = array ();
  40.             foreach ( $this->prevRule->deny as $nextRule ) {
  41.                 $data [] = new SentencialForm ( $this->rules, $this->form, $nextRule, $this->seekSentence, $this->step + 1, $this );
  42.             }
  43.             return $data;
  44.         } else {
  45.             return false;
  46.         }
  47.     }
  48.  
  49.     public function isDone() {
  50.         return $this->form == $this->seekSentence;
  51.     }
  52.  
  53.     public function getTrace() {
  54.         $trace = array ();
  55.         $parent = $this;
  56.         while ( $parent != null ) {
  57.             $trace [] = $parent;
  58.             $parent = $parent->parent;
  59.         }
  60.         return array_reverse ( $trace );
  61.     }
  62.  
  63.     public function toString() {
  64.         return "[" . $this->step . "](" . $this->form . "," . $this->prevRule->index . ")";
  65.     }
  66.  
  67.     public function printTrace() {
  68.         $trace = $this->getTrace ();
  69.         foreach ( $trace as $sentence ) {
  70.             echo $sentence->toString () . "\r\n";
  71.         }
  72.     }
  73.  
  74. }
  75.  
  76. class Rule {
  77.  
  78.     public function __construct($index, $lSide, $rSide, $allow, $deny) {
  79.         $this->index = $index;
  80.         $this->lSide = $lSide;
  81.         $this->rSide = $rSide;
  82.         $this->allow = $allow;
  83.         $this->deny = $deny;
  84.     }
  85.  
  86. }
  87.  
  88. class Rules {
  89.  
  90.     public function __construct($ruleStr) {
  91.         $rs = explode ( "\n", trim ( $ruleStr ) );
  92.         $this->rules = array_map ( function ($x) {
  93.             $toInt = function ($x) {
  94.                 return $x * 1;
  95.             };
  96.             $x = explode ( ":", trim ( $x ), 2 );
  97.             $num = $toInt ( $x [0] );
  98.             $x = explode ( "->", $x [1], 2 );
  99.             $lSide = $x [0];
  100.             $x = explode ( "(", $x [1], 2 );
  101.             $rSide = $x [0];
  102.             $x = explode ( ")", $x [1], 2 );
  103.             $allow = $x [0] == "" ? array () : array_map ( $toInt, explode ( ",", $x [0] ) );
  104.             $x = explode ( ",(", $x [1], 2 );
  105.             $x = explode ( ")", $x [1], 2 );
  106.             $deny = $x [0] == "" ? array () : array_map ( $toInt, explode ( ",", $x [0] ) );
  107.             return new Rule ( $num, $lSide, $rSide, $allow, $deny );
  108.         }, $rs );
  109.         $getR = function ($rules, $index) {
  110.             foreach ( $rules as $rule ) {
  111.                 if ($rule->index == $index) {
  112.                     return $rule;
  113.                 }
  114.             }
  115.             return false;
  116.         };
  117.  
  118.         foreach ( $this->rules as $rule ) {
  119.             $dataAllow = array ();
  120.             foreach ( $rule->allow as $allowI ) {
  121.                 $x = $getR ( $this->rules, $allowI );
  122.                 if ($x === false) {
  123.                     die ( "Invalid allow rule: " . $allowI );
  124.                 }
  125.                 $dataAllow [] = $x;
  126.             }
  127.             $dataDeny = array ();
  128.             foreach ( $rule->deny as $deniedI ) {
  129.                 $x = $getR ( $this->rules, $deniedI );
  130.                 if ($x === false) {
  131.                     die ( "Invalid deny rule: " . $deniedI );
  132.                 }
  133.                 $dataDeny [] = $x;
  134.             }
  135.             $rule->allow = $dataAllow;
  136.             $rule->deny = $dataDeny;
  137.         }
  138.     }
  139.  
  140. }
  141.  
  142. function parse($sentenceI, $printFailed, $printGood, $printResultInfo) {
  143.     $ruleStr = "1:S->SC(1,2),()
  144. 2:S->AA(3),()
  145. 3:A->B(4),(5)
  146. 4:C->D(3),(7)
  147. 5:C->C(6),()
  148. 6:B->A(6),(3)
  149. 7:B->A(7),(8)
  150. 8:D->A(9),(10)
  151. 9:D->C(9),(3)
  152. 10:A->a(10),()";
  153.  
  154.     $rules = new Rules ( $ruleStr );
  155.     $sentence = new SentencialForm ( $rules->rules, "S", $rules->rules [0], $sentenceI );
  156.  
  157.     $stack = array (
  158.             $sentence
  159.     );
  160.     while ( count ( $stack ) > 0 ) {
  161.         $sentence = array_shift ( $stack );
  162.         if ($sentence->isDone ()) {
  163.             if ($printGood) {
  164.                 echo "\r\n";
  165.                 echo "Finished:\r\n";
  166.                 $sentence->printTrace ();
  167.             }
  168.             if ($printResultInfo) {
  169.                 echo "Accepted sentence " . $sentenceI . "\r\n";
  170.             }
  171.             return true;
  172.         }
  173.         $expanded = false;
  174.         $nextSentences = $sentence->isApplicable ();
  175.         if ($nextSentences !== false) {
  176.             foreach ( $nextSentences as $nextSentence ) {
  177.                 $stack [] = $nextSentence;
  178.                 $expanded = true;
  179.             }
  180.         }
  181.         if (! $expanded) {
  182.             if ($printFailed) {
  183.                 echo "\r\n";
  184.                 echo "Failed:\r\n";
  185.                 $sentence->printTrace ();
  186.                 echo "\r\n";
  187.             }
  188.         }
  189.     }
  190.     if ($printResultInfo) {
  191.         echo "Rejected sentence " . $sentenceI . "\r\n";
  192.     }
  193.     return false;
  194. }
  195.  
  196. $s = "a";
  197. for($i = 0; $i < 100; $i ++) {
  198.     if (parse ( $s, false, false, false )) {
  199.         echo "Accepted: " . strlen ( $s ) . "\r\n";
  200.     }
  201.     $s .= "a";
  202. }
  203. //parse ( "aaa", false, false, true );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement