对编译原理有兴趣的进
include 'ttrie.php';<br> <br> class Rule extends TTrie {<br> public $rule = array();<br> public $savematch = 0;<br> <br> function __construct($s='') {<br> $this->set( array(<br> ' ' => 'Separated',<br> "\r\n" => 'set_rule',<br> "\n" => 'set_rule',<br> "\t" => 'Separated',<br> '->' => 'Separated',<br> '→' => 'Separated',<br> '|' => 'set_parallel_rule',<br> ));<br> $this->match($s);<br> if($this->rule[0][0] == $this->rule[0][1]) {<br> if(count($this->rule[0]) == 2) $this->rule[0][0] .= "'";<br> else array_unshift($this->rule, array($this->rule[0][0]."'", $this->rule[0][0]));<br> }else {<br> $c = $this->rule[0][0];<br> $n = 0;<br> foreach($this->rule as $r) if($r[0] == $c) $n++;<br> if($n > 1) array_unshift($this->rule, array($this->rule[0][0]."'", $this->rule[0][0]));<br> }<br> }<br> function Separated() {<br> }<br> function set_rule() {<br> $this->rule[] = $this->buffer;<br> $this->buffer = array();<br> }<br> function set_parallel_rule() {<br> $t = $this->buffer[0];<br> $this->set_rule();<br> $this->buffer[] = $t;<br> }<br> }<br> <br> <br> class Grammar {<br> var $closure = array();<br> var $first = array();<br> var $follow = array();<br> var $rule = array();<br> var $identifier = array();<br> var $leay = array();<br> var $forecast = array();<br> var $stack = array();<br> var $ll = 'LL(0)';<br> var $lr = 'LR(0)';<br> <br> function __construct($s='') {<br> $p = new Rule($s);<br> $this->rule = $p->rule;<br> $this->set_grammar();<br> }<br> <br> function set_grammar() {<br> foreach($this->rule as $rule) {<br> if(! in_array($rule[0], $this->identifier)) $this->identifier[] = $rule[0];<br> }<br> foreach($this->rule as $rule) {<br> foreach($rule as $v)<br> if(! in_array($v, $this->identifier) && ! in_array($v, $this->leay))<br> $this->leay[] = $v;<br> }<br> $this->set_first();<br> $this->set_follow();<br> $this->set_closure();<br> $this->set_select();<br> $this->set_forecast();<br> }<br> function set_first() {<br> foreach($this->rule as $rule) $this->first[$rule[0]] = array();<br> //直接收取 形如U->a…的产生式(其中a是终结符),把a收入到First(U)中<br> foreach($this->rule as $v) {<br> if(in_array($v[1], $this->leay)) $this->first[$v[0]][] = $v[1];<br> }<br> //反复传递 形入U->P1P2P3…Pn的产生式(其中P是非终结符),应先把First(P1)中的全部内容传送到First(U)中,如果P1中有ε,把First(P2)中的内容传送到First(U)中,类推直到Pi中无ε<br> do {<br> $t = serialize($this->first);<br> foreach($this->rule as $rule) {<br> for($i=1; $i<count class="clear"> </count>