編譯原理 消除左遞歸,直接左遞歸、間接左遞歸

消除左遞歸

左遞歸的定義

如果存在非終結符PP經過一步或一步以上推導出PαP\alpha,即
P+PαP\stackrel{+}{\Longrightarrow}P\alpha則稱PP含有左遞歸。

  • 含有左遞歸的文法將使自上而下的分析過程1陷入無限循環。

左遞歸的消除

消除直接左遞歸

假定關於非終結符PP的規則爲PPαβP\to P\alpha|\beta其中,β\beta不以PP開頭。即,PP所能確定的是以β\beta開頭、以若干個α\alpha結尾的語言。
那麼,可以把PP的規則改寫爲下面的非直接左遞歸形式:
PβPP\to \beta P' PαPεP'\to \alpha P'|\varepsilon

  • 舉個例子:文法

EE+TTE\to E+T|T TTFFT\to T*F|F F(E)iF\to (E)|i 經過消去直接左遞歸後變成 ETEE\to TE' E+TEεE'\to +TE'|\varepsilon TFTT\to FT' TFTεT'\to *FT'|\varepsilon F(E)i F\to (E)|i

消除間接左遞歸

先將間接左遞歸變爲直接左遞歸,再按消除直接左遞歸的方法進行。

  • 舉個例子,文法G[A]

ABcdA\to Bc|d BaAAbB\to aA|Ab 轉換爲直接左遞歸(代入) AaAcAbcdA\to aAc|Abc|d 消除直接左遞歸 AaAcAdAA\to aAcA'|dA' AbcAεA'\to bcA'|\varepsilon 簡化爲 A(aAcd)AA\to (aAc|d)A' AbcAεA'\to bcA'|\varepsilon

消除全部左遞歸

前提:該文法不含迴路2

  1. 把文法中所有非終結符按任意一種順序排列成P1,P2,P3,PnP_{1},P_{2},P_{3}\cdots,P_{n}

  2. 對每個非終結符號,用排在它前面的其他非終結符號的產生式表示出來(代入),並消除產生式中的直接左遞歸。

  3. 化簡上一步所得文法,即去掉重複、多餘的產生式。

  • 舉個例子,文法G[S]

SQccS\to Qc|c QRbbQ\to Rb|b RSaaR\to Sa|a 1. 對非終結符排序:R,Q,S
2. 逐個消除直接左遞歸:R:RSaaR:R\to Sa|a 無直接左遞歸,將RR代入QQQSababbQ\to Sab|ab|b 無直接左遞歸,將RRQQ代入SSSSabcabcbccS\to Sabc|abc|bc|c 消除SS的直接左遞歸:S(abcbcc)SS\to(abc|bc|c)S' SabcSεS'\to abcS'|\varepsilon 現文法爲:S(abcbcc)SS\to (abc|bc|c)S' SabcSεS'\to abcS'|\varepsilon QSababbQ\to Sab|ab|b RSaaR\to Sa|a 3. 去掉多餘產生式 S(abcbcc)SS\to (abc|bc|c)S' SabcSεS'\to abcS'|\varepsilon

注意:對非終結符的排序是任意的(但要保證其識別的符號不變),不同的排序最後所得文法的形式可能不同,但他們是等價的。


  1. 自上而下就是從文法的開始符號出發,向下推導,推出句子。 ↩︎

  2. 形如PPP\to P的推導,也不含有以ε\varepsilon爲右部的產生式。 ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章