能使用自顶向下分析技术的文法必须是LL(1)文法
常见考点:
- 计算三大集( F I R S T FIRST FIRST, F O L L O W FOLLOW FOLLOW, S E L E C T SELECT SELECT)。
- 判断文法是否 L L ( 1 ) LL(1) LL(1)文法,如果是,应该会构造其分析表。
- 改写/构造等价文法:主要应用消除左递归的方法。
- 给定输入串,检测其是否为文法对应的句子?
本文档主要讲解在编译原理一课中上述考点的解题技巧。
求解三大集合
-
求解三大集之前,应该先看非终结符最后是否能够为空,这能够帮助答者更谨慎地处理 F O L L O W FOLLOW FOLLOW集、快速地确定 S E L E C T SELECT SELECT集。
-
三大集规则
-
F I R S T FIRST FIRST集
(主要查找箭头右边第一个元素,求解的目标字母应该在箭头左边)
- A → a B A→aB A→aB, a a a加入 F I R S T ( A ) FIRST(A) FIRST(A)
- A → ξ A→\xi A→ξ, ξ \xi ξ加入 F I R S T ( A ) FIRST(A) FIRST(A)
- A → X a A→Xa A→Xa, F I R S T ( X ) ÷ ξ FIRST(X)÷\xi FIRST(X)÷ξ加入 F I R S T ( A ) FIRST(A) FIRST(A)中
-
F O L L O W FOLLOW FOLLOW集
(求解目标字母应该在箭头右边,主要查找目标字母右边的元素)
- 若目标字母为开始符号,则其 F O L L O W FOLLOW FOLLOW集内必须有一个#
- B → A a B→Aa B→Aa, F O L L O W ( A ) FOLLOW(A) FOLLOW(A)中有 a a a
- B → A C B→AC B→AC, F O L L O W ( A ) FOLLOW(A) FOLLOW(A)中加入 F I R S T ( C ) ÷ ξ FIRST(C)÷\xi FIRST(C)÷ξ
- B → a A B→aA B→aA或 B → a A C B→aAC B→aAC且 C → ξ C→\xi C→ξ成立,将 F O L L O W ( B ) FOLLOW(B) FOLLOW(B)加入 F O L L O W ( A ) FOLLOW(A) FOLLOW(A)
注: F O L L O W FOLLOW FOLLOW集中没有 ξ \xi ξ
-
S E L E C T SELECT SELECT集
- S E L E C T ( E → T E ′ ) = F I R S T ( T E ′ ) = F I R S T ( T ) SELECT(E→TE')=FIRST(TE')=FIRST(T) SELECT(E→TE′)=FIRST(TE′)=FIRST(T),此时 T E ′ TE' TE′是确定不为空的
- S E L E C T ( E ′ → ξ ) = ( F I R S T ( ξ ) − ξ ) ∪ F O L L O W ( E ′ ) SELECT(E'→\xi)=(FIRST(\xi)-{\xi})∪FOLLOW(E') SELECT(E′→ξ)=(FIRST(ξ)−ξ)∪FOLLOW(E′),当然这里的 ξ \xi ξ是指代箭头后面为空的情况,复杂一点的话题目是会给出箭头指向其他非终结符的情况,此时要注意该非终结符是否为空,因此,确定非终结符最后是否为空非常重要。
Q:有没有快速求解/验证 S E L E C T SELECT SELECT集的方法?
A:有,这个办法就是绘制语法树找首个终结符(其实就是利用了 S E L E C T SELECT SELECT规则1的特性,这个方法也可以认为是快速求解 F I R S T FIRST FIRST集的方法),当然如果遇到箭头右边指空的情况,也还是要老老实实求 F O L L O W FOLLOW FOLLOW集。
实践如下:
-
L L ( 1 ) LL(1) LL(1)文法判别
要求不含左递归且满足相关定义。
定义:相同左部产生式 S E L E C T SELECT SELECT交集为空可以认为该方法为 L L ( 1 ) LL(1) LL(1)的
即当 S E L E C T ( A → α ) ∩ S E L E C T ( A → β ) = ∅ SELECT(A→\alpha)∩SELECT(A→\beta)=∅ SELECT(A→α)∩SELECT(A→β)=∅,可认为这个文法是满足 L L ( 1 ) LL(1) LL(1)条件的。
实现非 L L ( 1 ) LL(1) LL(1)文法到 L L ( 1 ) LL(1) LL(1)文法的等价转换
方法提炼
当有 B → a B c ∣ B b c ∣ d ∣ . . . B→aBc|Bbc|d|... B→aBc∣Bbc∣d∣...,可以看成形如 B → B α ∣ β ∣ β ′ ∣ . . . B→B\alpha|\beta|\beta'|... B→Bα∣β∣β′∣...的形式(提取产生式右边自己牵头的,即自己不在产生式右端首位的全部归类为 β \beta β 即可:
转化为:
B → ( β ∣ β ′ ) B ′ B→(\beta|\beta')B' B→(β∣β′)B′
B ′ → α B ′ ∣ ξ B'→\alpha B'|\xi B′→αB′∣ξ
一定要按格式说话!!!
L L ( 1 ) LL(1) LL(1)分析的实现(表驱动)
步骤:
-
判断是否由左递归,有左递归就要消除左递归
-
求解三大集
-
构造预测分析表(根据 S E L E C T SELECT SELECT集情况来完善,表行项为各项非终结符,表列项为各项终结符)
-
对符号串进行分析(步骤 分析栈 剩余输入串 操作)
步骤1中的分析栈需要是# E E E!!!(追溯到自顶向下语法分析方法的本质)