FOLLOW(T)={+,),#} FOLLOW(T’)={+,),#} FOLLOW(F)={(,a,b,∧,+,),#} FOLLOW(F’)={(,a,b,∧,+,),#} FOLLOW(P)={*,(,a,b,∧,+,),#} (2) 本文法是LL ( 1 )文法。
证明: 通过观察可知文法中不含有左递归,满足LL (1)文法定义的第一
个条件。
考虑下列产生式: E’→+E∣ε T’→T∣ε F’→*F’∣ε P→(E)∣a∣b∣∧ 因为: FIRST(+E)∩FIRST(ε)={+}∩{ε}=? FIRST(E’)∩FOLLOW(E’)={+}∩{#,)}= ? FIRST(T)∩FIRST(ε)={(,a,b,∧}∩{ε}=? FIRST(T’)∩FOLLOW(T’)={(,a,b,∧}∩{+,),#}=? FIRST(*F’)∩FIRST(ε)={*}∩{ε}=? FIRST(F’)∩FOLLOW(F’)={*}∩{(,a,b,∧,+,),#}= ? FIRST((E))∩FIRST(a)∩FIRST(b)∩FIRST(∧)= ? 所以该文法是LL(1)文法。 (3) 构造其预测分析表:
预测分析表 + * ( ) a b ^ E E?T E’ E?T E’ E?T E’ E?T E’ E’ ?ξ E’ E’?+E T’?FT’ T?FT’ T?FT’ T T ?FT’ T’?ξ T’?ξ T’?T T’ T’ ? T T’?T T’ ?T F?PF’ P?PF’ F?PF’ F F ?PF’ F’ ? ξ F’ ?*F’ F’ ? ξ F’?ξ F’?ξ F’?ξ F’?ξ F’ P P ?(E) P?a P?b P? ^ (4) 构造其递归下降分析程序: Procedure E; Begin T ; E’ End ;
Procedure E’ ; Begin If sym = ‘ + ’
# E’ ->ξ T’?ξ F’?ξ Then begin Acvance ; E End End ;
Procedure T ; Begin F ; T’ End ;
Procedure T’ ; Begin If sym ∈first ( T ) Then T
Else if sym = ‘*’ then error End ;
Procedure F ; Begin
If sym ∈first ( P ) P; F’; End ;
Procedure F’ Begin If sym = ‘ * ’ Then begin Advance ; F’ End End;
Procedure P Begin
If sym = ‘ a ’ or sym = ‘ b ‘ or sym = ‘ ^
Then acvance Else if sym = ‘ ( ‘ Then begin Advance ; E ;
If sym = ‘ ) ‘ Then advance Else error End
Else error
End;
3、下面文法中,哪些是LL(1)的,说明理由。 (1)、 S→Abc A→a∣ε B→b∣ε (2)、 S→Ab A→a∣B∣ε B→b∣ε (3)、 S→ABBA A→a∣ε B→b∣ε
(4)、 S→aSe∣B B→bBe∣C C→cCe∣d
分析:判断文法是否是LL(1)的,要根据LL(1)文法的条件逐一检查:首先要确定文法不含左递归;随后计算文法的各非终结符(X)的首符集FIRST(X)和随符集FOLLOW(X)。首先要理解这两个集合的计算方法,特别要注意算法终止的条件:直到集合不再变化为止。也就是说,反复检查每一个产生式,直到从头到尾检查了所有产生式,而FIRST集合和FOLLOW集合都没有变化了,这时候计算才能结束。最后根据LL(1)文法的充分必要条件(即LL(1)文法定义)来判断是否是LL(1)文法。 解:
(1) 该文法不含左递归,计算每个非终结符的FIRST集合和FOLLOW集
合如下:
FIRST(S)={a,b,c} FIRST(A)={a,ε} FIRST(B)={b,ε} FOLLOW(S)={#} FOLLOW(A)={b,c} FOLLOW(B)={c} 可见该文法满足LL(1)文法的三个条件,是LL(1)文法。
(2) 该文法不含左递归,计算每个非终结符的FIRST集合和FOLLOW集
合如下:
FIRST(S)={a,b} FIRST(A)={a,b,ε}
FIRST(B)={b,ε} FOLLOW(S)={#} FOLLOW(A)={b} FOLLOW(B)={b} 考虑A→a∣B∣ε,因为FIRST(B)∩FOLLOW(A)={b}≠?,所以该文法不是LL(1)文法。
(3) 该文法不含左递归,计算每个非终结符的FIRST集合和FOLLOW集
合如下:
FIRST(S)={a,b,ε} FIRST(A)={a,ε} FIRST(B)={b,ε} FOLLOW(S)={#} FOLLOW(A)={a,b,#} FOLLOW(B)={a,b,#} 考虑A→a∣ε和B→b∣ε,因为 FIRST(a)∩FOLLOW(A)={a}≠? FIRST(b)∩FOLLOW(B)={b}≠?
所以该文法不是LL(1)文法。
(4) 该文法不含左递归,计算每个非终结符的FIRST集合和FOLLOW集
合如下:
FIRST(S)={a,b,c,d} FIRST(B)={b,c,d} FIRST(C)={c,d} FOLLOW(S)={e,#} FOLLOW(B)={e,#} FOLLOW(C)={e,#} 可见该文法满足LL(1)文法的三个条件,是LL(1)文法。
4、对下面文法: Expr→-Expr
Expr→(Expr)∣Var ExprTail→-Expr∣ε Var→id VarTail VarTail→(Expr)∣ε (1)、构造LL(1)分析表。 (2)、给出对句子id--id((id))的分析过程。
分析:构造文法的预测分析表,通常应当按下列顺序进行:(1)、消除文法的左递归(包括所有直接左递归和间接左递归);(2)、对消除左递归后的文法,提取左公因子;(3)、对经过上述改造后的文法,计算它的每个非终结符的FIRST集合和FOLLOW集合;(4)、根据FIRST集合和FOLLOW集合构造预测分析表。 第一步对文法G的每个产生式A→α执行第一步和第三步;第二步对每个终结符a∈FIRST(α),把A→α加至M[A,a]中;第三步若ε∈FIRST(α),则对任何b∈FOLLOW(A)把A→α加至M[A,b]中;第四步把所有无定义的M[A,a]标上“出错标志”。
解: (1)、计算每个非终结符的FIRST集合和FOLLOW集合如下: FIRST(Expr)={-,(,id} FIRST(ExprTail)={-,ε} FIRST(Var)={id}
FIRST(VarTail)={(,ε} FOLLOW(Expr)={),#} FOLLOW(ExprTail)={),#} FOLLOW(Var)={-,),#}
FOLLOW(VarTail)={-,∣,#} 构造其预测分析表如下: - id ( ) # Expr Expr→- Expr Expr Expr Expr→ -( Expr) ExprTail ExprTail→-Expr ExprTail→ε ExprTail→ε Var Var→id VarTail VarTail VarTail→ε VarTail→VarTail→ε VarTail→ε (Expr) (2)、句子id--id((id))的分析过程如下: 步骤 符号栈 输入串 所用产生式 0 # Expr id--id((id)) # 1 # ExprTail Var id--id((id)) # Expr→Var ExprTail 2 # ExprTail VarTail id id--id((id)) # Var→id VarTail 3 # ExprTail VarTail --id((id)) # 4 # ExprTail --id((id)) # VarTail→ε 5 # Expr - --id((id)) # ExprTail→-Expr 6 # Expr -id((id)) # 7 # Expr - -id((id)) # Expr→-Expr 8 # Expr id((id)) # 9 # ExprTail Var id((id)) # Expr→Var ExprTail 10 # ExprTail VarTail id id((id)) # Var→id VarTail 11 # ExprTail VarTail ((id)) # 12 # ExprTail ) Expr ( ((id)) # VarTail→(Expr) 13 # ExprTail ) Expr (id)) # 14 # ExprTail ) ) Expr ( (id)) # 15 # ExprTail ) ) Expr id)) # 16 # ExprTail ) ) ExprTal Var id)) # Expr→Var ExprTail 17 # ExprTail ) ) ExprTail VarTail id id)) # Var→id VarTail 18 # ExprTail ) ) ExprTail VarTail )) # 19 # ExprTail ) ) ExprTail )) # VarTail→ε