LL(1)文法:
例题:
First集:
first算法:
求非终结符的first集:
扫描以要求first集的非终结符为左部的各产生式的右部,分为下面几种情况:
- 若遇到终结符,将该终结符加入左部非终结符的first集,继续扫描下一产生式;
- 若遇到符号“ε”,将“ε”加入左部非终结符的first集,继续扫描下一产生式;
- 若遇到非终结符,将该非终结符的 first集— {ε}
加入左部非终结符的first集,然后检查该非终结符是否可以推出空,若可以为空,则扫描本产生式的下一符号;若不为空,则继续扫描下一产生式; - 若遇到“\0”,将“ε”加入左部非终结符的first集,继续扫描下一产生式;
求FOLLOW集
- FOLLOW集合是从开始符号S开始推导,把#加入FOLLOW(S)中。
- 左部是S的产生式,右部末尾是非终结符,则把#加入此非终结符的FOLLOW集中。
- 右部中若某非终结符的后面是终结符,则把此终结符加入到非终结符的FOLLOW集中。
- 右部中若某非终结符的后面是非终结符,
若后非终结符能推出空字符,则把后非终结符的FIRST集(去掉空字符)传送到前非终结符的FOLLOW集中,同时把左部非终结符的FOLLOW集传送到后非终结符的FOLLOW集中。
若后非终结符不能推出空字符,则把后非终结符的FIRST集传送到前非终结符的FOLLOW集中。
例如:S->AB A→ε A→b B→ε B→aD
通过以上的方法可以知道:
- B→ε ,
则first(B)— 除去 ε —>Follow(A)
Follow(S)——>Follow(B)
- B不能推出ε ,
则first(S)——>Follow(A)
注意:ε是终结符
例题:
S→AB
S→bC
A→ε
A→b
B→ε
B→aD
C→AD
C→b
D→aS
D→c
求first集合:
(1) 通过第一条产生式:A是非总结符,则等待A求出first集合
(2) 通过第二条产生式:可以得到S的first集={b}
(3) 通过第三条产生式:可以知道A的first集={ε}
(4) 通过第四条产生式:可以知道A的first集={b}
通过(3)(4)可以知道A的first集={ε、b},因为A可以为空,所以要求得到B的first集才能知道S的first集
(5) 通过第五条产生式:可以知道B的first集={ε}
(6) 通过第六条产生式:可以知道B的first集={a}
- 可得B的first集={ε、a},可以知道S的first集={ε、a、b}
(7) 通过第七条产生式:可以知道C的first集要知道A、D的first集合,
(8) 通过第八条产生式:可以知道C的first集={b}
(9) 通过第九条产生式:可以知道D的first集={a}
(10) 通过第十条产生式:可以知道D的first集={c}
-
可得到D的first集={a、c},通过知道A、D的first集可得C的first集={a、b、c}
解释为何C的first集为何没有空,是因为D的first集比为空
通过整理First集:
S的first集={ε、a、b}
A的first集={ε、b}
B的first集={ε、a}
C的first集={a、b、c}
D的first集={a、c}
求Follow集:
(11) 通过第一条产生式:首先,从开始符号S开始推导,所以follow(S)集={#},其次,左部是S的产生式,第一二条产生式满足条件,右部末尾是非终结符,则把#加入此非终结符的FOLLOW集中。由上可知follow(B)={#},follow(C)={#}。
-
且A为非终结符当不为空,非终结符的后面是非终结符B,非终结符B能够推出为ε,则把后非终结符B的FIRST集(去掉空字符)传送到前非终结符的FOLLOW集中,可以得到follow(A)集={a}。同时把左部非终结符S的FOLLOW集传送到后非终结符B的FOLLOW集中,follow(B)={#}
-
但是非终结符A可以推出为空,则当A为空集,则非终结符B是前终结符,非终结符的后面是终结符ε,则把此终结符加入到非终结符的FOLLOW集中,可得follow(B)={#}
(12) 通过第二条产生式:可以知道非终结符C的后面是终结符ε,则把此终结符加入到非终结符的FOLLOW集中。可以知道follow(C)={#}
(13) 通过第三,四条产生式:不能明确任何信息
(14) 通过第五条产生式:非终结符D,可知非终结符后面式终结符ε,则把此终结符加入到非终结符的 FOLLOW集中,可以知道follow(D)={#}
(15) 通过第六条产生式:不能明确任何信息
(16) 通过第七条产生式:
- A为非终结符当推出不为空,非终结符的后面是非终结符D,非终结符D不能够推出为ε,则把后非终结符的FIRST集传送到前非终结符的FOLLOW集中。可得follow(A)={#,a,c}
- 但是非终结符A可以推出为空,则当A为空集,则非终结符D是前终结符,非终结符的后面是终结符ε,则把此终结符加入到非终结符的FOLLOW集中,可得follow(D)={#}
(17) 通过第八条产生式:不能明确任何信息
(18) 通过第九条产生式:不推S
(19) 通过第十条产生式:不能明确任何信息
通过整理:
follow(S)集={#}
follow(A)={#,a,c}
follow(B)={#}
follow(C)={#}
follow(D)={#}
求Select集的方法:
求解方法:
1.如果 α 不能推出 ε,则:SELECT(A → α) = FIRST(α)
2.如果 α 推出 ε,则:SELECT(A → α) = ( FIRST(α) – {ε} ) ∪ FOLLOW(A)
产生式的select集如下:
SELECT(S→AB)= {b,a,#} SELECT(S→bC)=={b}
SELECT(A→ε)= {a,c,#} SELECT(A→b)= {b}
SELECT(B→ε)= {#} SELECT(B→aD)={a}
SELECT(C→AD)= {b,a,c} SELECT(C→b) ={b}
SELECT(D→aS)= {a} SELECT(D→c)= {c}
由于
SELECT(S→AB)∩SELECT(S→bC)={b}≠ф
SELECT(C→AD)∩SELECT(C→b)={b}≠ф
所以文法G[S]不是LL(1)文法