消除左遞歸
左遞歸的定義
如果存在非終結符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′∣ε
注意:對非終結符的排序是任意的(但要保證其識別的符號不變),不同的排序最後所得文法的形式可能不同,但他們是等價的。