消除左递归
左递归的定义
如果存在非终结符
P
P
P经过一步或一步以上推导出
P
α
P\alpha
Pα,即
P
⟹
+
P
α
P\stackrel{+}{\Longrightarrow}P\alpha
P⟹+Pα则称
P
P
P含有左递归。
- 含有左递归的文法将使自上而下的分析过程1陷入无限循环。
左递归的消除
消除直接左递归
假定关于非终结符
P
P
P的规则为
P
→
P
α
∣
β
P\to P\alpha|\beta
P→Pα∣β其中,
β
\beta
β不以
P
P
P开头。即,
P
P
P所能确定的是以
β
\beta
β开头、以若干个
α
\alpha
α结尾的语言。
那么,可以把
P
P
P的规则改写为下面的非直接左递归形式:
P
→
β
P
′
P\to \beta P'
P→βP′
P
′
→
α
P
′
∣
ε
P'\to \alpha P'|\varepsilon
P′→αP′∣ε
- 举个例子:文法
E → E + T ∣ T E\to E+T|T E→E+T∣T T → T ∗ F ∣ F T\to T*F|F T→T∗F∣F F → ( E ) ∣ i F\to (E)|i F→(E)∣i 经过消去直接左递归后变成 E → T E ′ E\to TE' E→TE′ E ′ → + T E ′ ∣ ε E'\to +TE'|\varepsilon E′→+TE′∣ε T → F T ′ T\to FT' T→FT′ T ′ → ∗ F T ′ ∣ ε T'\to *FT'|\varepsilon T′→∗FT′∣ε F → ( E ) ∣ i F\to (E)|i F→(E)∣i
消除间接左递归
先将间接左递归变为直接左递归,再按消除直接左递归的方法进行。
- 举个例子,文法G[A]
A → B c ∣ d A\to Bc|d A→Bc∣d B → a A ∣ A b B\to aA|Ab B→aA∣Ab 转换为直接左递归(代入) A → a A c ∣ A b c ∣ d A\to aAc|Abc|d A→aAc∣Abc∣d 消除直接左递归 A → a A c A ′ ∣ d A ′ A\to aAcA'|dA' A→aAcA′∣dA′ A ′ → b c A ′ ∣ ε A'\to bcA'|\varepsilon A′→bcA′∣ε 简化为 A → ( a A c ∣ d ) A ′ A\to (aAc|d)A' A→(aAc∣d)A′ A ′ → b c A ′ ∣ ε A'\to bcA'|\varepsilon A′→bcA′∣ε
消除全部左递归
前提:该文法不含回路2
-
把文法中所有非终结符按任意一种顺序排列成 P 1 , P 2 , P 3 ⋯ , P n P_{1},P_{2},P_{3}\cdots,P_{n} P1,P2,P3⋯,Pn;
-
对每个非终结符号,用排在它前面的其他非终结符号的产生式表示出来(代入),并消除产生式中的直接左递归。
-
化简上一步所得文法,即去掉重复、多余的产生式。
- 举个例子,文法G[S]
S
→
Q
c
∣
c
S\to Qc|c
S→Qc∣c
Q
→
R
b
∣
b
Q\to Rb|b
Q→Rb∣b
R
→
S
a
∣
a
R\to Sa|a
R→Sa∣a 1. 对非终结符排序:R,Q,S
2. 逐个消除直接左递归:
R
:
R
→
S
a
∣
a
R:R\to Sa|a
R:R→Sa∣a 无直接左递归,将
R
R
R代入
Q
Q
Q:
Q
→
S
a
b
∣
a
b
∣
b
Q\to Sab|ab|b
Q→Sab∣ab∣b 无直接左递归,将
R
R
R,
Q
Q
Q代入
S
S
S:
S
→
S
a
b
c
∣
a
b
c
∣
b
c
∣
c
S\to Sabc|abc|bc|c
S→Sabc∣abc∣bc∣c 消除
S
S
S的直接左递归:
S
→
(
a
b
c
∣
b
c
∣
c
)
S
′
S\to(abc|bc|c)S'
S→(abc∣bc∣c)S′
S
′
→
a
b
c
S
′
∣
ε
S'\to abcS'|\varepsilon
S′→abcS′∣ε 现文法为:
S
→
(
a
b
c
∣
b
c
∣
c
)
S
′
S\to (abc|bc|c)S'
S→(abc∣bc∣c)S′
S
′
→
a
b
c
S
′
∣
ε
S'\to abcS'|\varepsilon
S′→abcS′∣ε
Q
→
S
a
b
∣
a
b
∣
b
Q\to Sab|ab|b
Q→Sab∣ab∣b
R
→
S
a
∣
a
R\to Sa|a
R→Sa∣a 3. 去掉多余产生式
S
→
(
a
b
c
∣
b
c
∣
c
)
S
′
S\to (abc|bc|c)S'
S→(abc∣bc∣c)S′
S
′
→
a
b
c
S
′
∣
ε
S'\to abcS'|\varepsilon
S′→abcS′∣ε
注意:对非终结符的排序是任意的(但要保证其识别的符号不变),不同的排序最后所得文法的形式可能不同,但他们是等价的。