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