Interested in compiling the principle of
Recently tried to do a grammar analysis of the east, more problems.
Please make suggestions. The code does not fit, two pages. Download Address http://download.csdn.net/detail/xuzuning/4529066
PHP Code
Include ' ttrie.php '; class Rule extends Ttrie {public $rule = array (); Public $savematch = 0; function __construct ($s = ') {$this->set (' = ' = ' separated ', ' \ r \ n ' = ' set_rule ', "\ n" = ' set_rule ', ' \ t ' and ' separated ', '-' and ' = ' separated ', ' → ' = ' separated ', ' | ' = ' set_parallel_rule ',)); $this->match ($s); if ($this->rule[0][0] = = $this->rule[0][1]) {if (count ($this->rule[0]) = = 2) $this->rule[0][0]. = "'"; else Array_unshift ($this->rule, Array ($this->rule[0][0]. "'", $this->rule[0][0])); }else {$c = $this->rule[0][0]; $n = 0; foreach ($this->rule as $r) if ($r [0] = = $c) $n + +; if ($n > 1) array_unshift ($this->rule, Array ($this->rule[0][0]. "'", $this->rule[0][0])); }} function separated () {} function Set_rule () {$this->rule[] = $this->buffer; $this->buffer = Array (); } function Set_parallel_rule () {$t = $this->buffer[0]; $this->set_rule (); $this->buffer[] = $t; }}class Grammar {var $closure = array (); var $first = array (); var $follow = array (); var $rule = array (); var $identifier = array (); var $leay = array (); var $forecast = array (); var $stack = array (); var $ll = ' ll (0) '; var $lr = ' lr (0) '; function __construct ($s = ") {$p = new Rule ($s); $this->rule = $p->rule; $this->set_grammar (); } function Set_grammar () {foreach ($this->rule as $rule) {if (! In_array ($rule [0], $this->identifier)) $t his->identifier[] = $rule [0]; } foreach ($this->rule as $rule) {foreach ($rule as $v) if (! In_array ($v, $this->identifier) &am p;&! In_array ($v, $this->leay)) $this->leay[] = $v; } $this->set_first (); $this->set_follow (); $this->set_closure (); $this->set_select (); $this->set_forecast (); } function Set_first () { foreach ($this->rule as $rule) $this->first[$rule [0]] = array (); Direct charge form like u->a ... (where A is terminator) and the A proceeds to the first (U) foreach ($this->rule as $v) {if (In_array ($v [1], $this->leay)) $this->first [$v [0]] [] = $v [1]; }//re-pass the form into the u->p1p2p3 ... The production of PN (where p is non-terminator), first (P1) should be transferred all of the contents into the first (U), if there is ε in P1, the contents of first (P2) is transferred to First (U), and so on until the pi is not εdo {$t = serialize ($this->first); foreach ($this->rule as $rule) {for ($i =1; $i
Identifier) {$this->first[$rule [0]] = Array_unique (Array_merge ($this->first[$rule [0]], $this-&G t;first[$v])); if (! In_array (' # ', $this->first[$v])) break; }else break; }}}while ($t! = Serialize ($this->first)); } function Set_follow () {foreach ($this->rule as $rule) $this->follow[$rule [0]] = array (); Direct charge of a form like ... Ua... , a direct income to the follow (U) foreach ($this->rule as $rule) {for ($i =1; $i
Identifier) && In_array ($rule [$i +1], $this->leay)) $this->follow[$rule [$i]][] = $rule [$i +1]; if (In_array ($rule [$i], $this->identifier)) $this->follow[$rule [$i]][] = ' # '; } foreach ($this->follow as & $v) if (! $v) $v [] = ' # '; Direct charge of a form like ... Up ... (P is non-terminator), the first (p) non-ε income to follow (U) in foreach ($this->rule as $rule) {for ($i =1; $i
Identifier) && In_array ($rule [$i +1], $this->identifier)) {$this->follow[$rule [$i]] = Array_ Unique (Array_merge ($this->follow[$rule [$i]], Array_diff ($this->first[$rule [$i +1]], array (' # '))); }}}//Repeat the U->AP (p is non-terminator) or U->APQ (P,q is not terminator and Q contains ε), the entire contents of the follow (U) should be transmitted to the Follow (p) do {$t = Serialize ($this->follow); foreach ($this->rule as $rule) {$s = $rule [0]; $d = End ($rule); if (In_array ($d, $this->leay)) continue; $p = prev ($rule); if (In_array ($p, $this->leay)) $this->follow[$d] = Array_unique (Array_merge ($this->follow[$d], $this- Follow[$s])); ElseIf (In_array (' # ', $this->follow[$d])) $this->follow[$p] = Array_unique (Array_merge ($this->follow[$p], $ This->follow[$s])); }}while ($t! = Serialize ($this->follow)); } function Set_closure () {$shift = array (); $this->closure[0][] = array (' offs '= 1, ' rule ' = 0); for ($i =0; $i < count ($this->closure); $i + +) {$cnt = count ($this->closure); Construct closure Closure $ex = Array (); $j = 0; $tmp = Array (); do {$size = count ($this->closure[$i]); for ($j =0; $j
closure[$i]); $j + +) {$dfa = $this->closure[$i] [$j]; $rule = $this->rule[$dfa [' rule ']; if (Isset ($rule [$DFA [' offs ']]) {$ch = $ex [] = $rule [$DFA [' offs ']]; } foreach ($this->rule as $r = + $rule) {if (In_array ($rule [0], $ex)) { $t = Array (' offs ' = = 1, ' rule ' = $r); if (!isset ($tmp [$r][1]) $this->closure[$i] = $t; $tmp [$r][1] = 1; }}}}while (count ($this->closure[$i])! = $size); Until no longer increases//judging status to go $out = array (); foreach ($this->closure[$i] as $k = = $dfa) {$rule = $this->rule[$dfa [' rule ']; if (Isset ($rule [$DFA [' offs ']]) {$t = "$dfa [rule], $dfa [offs]"; $ch = $rule [$dfa [' offs ']; $this->closure[$i [$k] [' char '] = $ch; IfIsset ($out [$ch]) $shift [$t] = $out [$ch]; if (Isset ($shift [$t])) {$this->closure[$i] [$k] [' target '] = $shift [$t]; $dfa [' offs ']++; if (! $this->in_closure ($DFA, $this->closure[$shift [$t]])) $this->closure[$shift [$t]][] = $DFA; } else {$cnt = count ($this->closure); $this->closure[$i [$k] [' target '] = $cnt; $shift [$t] = $cnt; $dfa [' offs ']++; $this->closure[count ($this->closure) [] = $DFA; $out [$ch] = $cnt; }}}//construct state Conversion table foreach ($this->closure[$i] as $k = = $dfa) {if (Isset ($dfa [' Target ']) {$v = $dfa [' char ']; if (In_array ($v, $this->identifier)) $this->goto[$i] [$v] = $DFA [' Target ']; else {$this->action[$i] [$v] [] = "s$dfa[target]"; $this->request[$i] [$v] = $dfa [' rule ']; }} else {$ch = $this->rule[$dfa [' rule ']][0]; foreach ($this->follow[$ch] as $v) {$this->action[$i] [$v] [] = "r$dfa[rule]"; $this->request[$i] [$v] = $dfa [' rule ']; }}} foreach ($this->action[$i] as $c = = $v) {$v = Array_unique ($v); if (count ($v) > 1) $this->lr = ' SLR (1) '; $this->action[$i] [$c] = $v; }}} function In_closure ($t, $s) {foreach ($s as $r) if ($t [' offs '] = = $r [' offs '] && $t [' rule '] = = $r [' Rul E ']) return true; return false; Return In_array (Serialize ($t), Array_map (' serialize ', $s)); } function Set_select () {foreach ($this->rule as $i = + $rule) {$y = Array ($rule [1]); if (In_array ($y [0], $this->leay)) {if ($y [0]! = ' # ') {$this->select[$i] = $y; Continue }}else $y = $this->first[$rule [1]]; $x = $this->follow[$rule [0]]; SELECT (X->y) = (First (Y)-{ε}) and follow (X) $this->select[$i] = Array_unique (Array_merge (Array_diff ($y, Array (' # ')), $x)); }}/** * Construct prediction Analysis Table **/function Set_forecast () {foreach ($this->select as $i + $r) {$c = $this->r ule[$i][0]; $v = Array_reverse (Array_slice ($this->rule[$i], 1)); foreach ($r as $k) {$this->forecast[$c] [$k] = $v; }}//Check conflict foreach ($this->forecast as $c + = $r) {foreach ($r as $k) {if (count ($k) > 1) {$this->ll = ' ll (1) '; } } } }