10.3 LL(1) 动作表及 LL(1) 解析

LL(1) 动作表用 M 表示,可以看成一个二维数组,或一个字典,动作表中的 M[A, a] 保存了在解析过程中当栈顶为非终结符 A 、读入的符号为 a 时所应采取的动作。动作表的构造过程为:

对语法中的每条产生式: A -> u :

(1) 对 First(u) 中的所有终结符 a (不含 ε ),置 M[A, a] = “A -> u” ;

(2) 若 First(u) 含 ε ,则对 Follow(A) 中的所有符号 a (可含 $ ),置 M[A, a] = “A -> u” 。

构造出动作表后,解析步骤为:

(1) 将结束符 $ 和起始符号 S 压入栈中;

(2) 从输入流中读入下一个终结符,赋给 a ,也就是执行一次 a = yylex() ;

(3) 设栈顶符号为 X ,有以下三种情况:

情况 A : X == a 且 a == $ ,解析成功,终止解析;

情况 B : X == a 且 a != $ ,执行 Match 动作,将 X 出栈,转到(2);

情况 C : X != a 且 X 是非终结符,有两种情况:

情况 C1 : M[X, a] = “X -> u”,执行 Predict 动作,将 X 出栈,压入 u ,转到(3);

情况 C2 : M[X, a] 未定义,输入不合语法,终止解析;

情况 D : X != a 且 X 是终结符,输入不合语法,终止解析。

下面来练习一下 LL(1) 分析法,语法为:

  1. E –> T E'
  2. E' –> + T E' | ε
  3. T –> F T'
  4. T' –> * F T' | ε
  5. F –> ( E ) | int

要解析的句子为: int + int * int 。

首先计算出所有非终结符的 first set 和 follow set :

  1. First(E) = First(T) = First(F) = { ( int }
  2. First(T') = { * ε}
  3. First(E') = { + ε}
  4. Follow(E) = Follow(E') { $ ) }
  5. Follow(T) = Follow(T') = { + $ ) }
  6. Follow(F) = { * + $ ) }

下面开始构造动作表 M 。

首先看第一个产生式: E -> T E’ 。 First(T E’) = { ( int } 。因此 M[E, (] = “E -> T E’” , M[E, int] = “E -> T E’” 。写成表格的形式:

int+*()$
EE -> T E’ E -> T E’
E’
T
T’
F

接下来看第二个产生式: E’ –> + T E’ 。 First( + T E’ ) = { + } 。因此 M[E’, +] = “E’ -> + T E’”。

再看第三个产生式: E’ -> ε 。 First( ε ) = { ε } ,且 Follow(E’) = { $ ) } ,因此 M[E’, $] = M[E’, )] = “E’ -> ε” 。都写到表格里面:

int+*()$
EE -> T E’ E -> T E’
E’ E’ –> + T E’ E’ -> εE’ -> ε
T
T’
F

重复以上方法,最终的分析表为:

int+()$
EE -> T E’ E -> T E’
E’ E’ –> + T E’ E’ -> εE’ -> ε
TT –> F T’ T –> F T’
T’ T’ –> εT’ –> F T’ T’ –> εT’ –> ε
FF –> int F –> ( E )

下面来解析句子 int + int * int :

Parse Stack Remaining Input Parse Action
E $ int + int int $ Predict E -> T E’
T E’ $ int + int int $ Predict T -> F T’
F T’ E’ $ int + int int $ Predict F -> int
int T’ E’ $ int + int int $ Match int
T’ E’ $ + int int $ Match int
T’ E’ $ + int int $ Predict T’ –> ε
E’ $ + int int $ Predict E’ –> + T E’
+ T E’ $ + int int $ Match +
T E’ $ int int $ Predict T –> F T’
F T’ E’ $ int int $ Predict F –> int
int T’ E’ $ int int $ Match int
T’ E’ $ int $ Predict T’ –> F T’
F T’ E’ $ int $ Match
F T’ E’ $ int $ Predict F –> int
int T’ E’ $ int $ Match int
T’ E’ $ $ Predict T’ –> ε
E’ $ $ Predict E’ –> ε
$ $ Match $, ACCEPT