如何消除左遞迴

2022-08-27 16:30:17 字數 1020 閱讀 7419

首先,什麼叫做左遞迴呢? 乙個左遞迴的語法通常有這樣的形式 :  a-> aa .而自頂向下的語法分析是無法處理左遞迴語法的。為什麼呢?無論是遞迴分析還是**分析或者是ll文法分析,在碰到左遞迴這種語法時都會陷入死迴圈當中。如果我們用遞迴分析,那麼在分析a這個非終結符號的時候就會呼叫functiona,functiona將a分解成a,a,然後在我們再次碰到a的時候又會呼叫functiona,這樣便形成了無限遞迴。如果我們用非遞迴的ll文法分析,那麼在我們將把a->aa無限次地壓入到棧中,即每次彈出a都會壓入aa。所以我們必須採取手段消除左遞迴,下面給出標準方法。

其中β1...βn 不是從a開始

其實原理在於通過轉換將a的語法不從非終結符號(a本身)開始,而是從終結符號β1...βn 開始。雖然a的原語法是從a本身開始的,但是第乙個符號一定是β1...βn中的乙個,而不可能是任何乙個α。所以我們通過乙個中間變數a'來表示剩下的α,然而不要忘記由於a' ->αa'  這條規則,a' -> ε 必須也存在於語法規則中,否則末尾將無法匹配完成。

但是,上述方法只適用於立即左遞迴,還有一種更隱蔽的非立即左遞迴,如 s -> aa | b , a -> sc | d ,我們如果用自頂向下的分析方法會陷入 s -> aa -> sca 這樣的死迴圈中。當然,也有相應的解決辦法。

將所有非終端符號以某個固定的順序

排列從 i = 1 到 n

}也許看上面的規則過於抽象,我們用s -> aa | b , a -> sc | d 來實踐一下上述的方法。我們以s,a的順序排列。則只需執行一次主程式體,且ai 為a,aj為s。則:

a -> aac | bc | d, 然後再運用前面的規則消除直接左遞迴可得:a -> bca' | da' , a'  -> aca' | ε 

請注意,以上的解決方案是基於右遞迴的文法,並不是完全適用於所有的情況。我們得到的文法可能含有 ε表示式,並且可能會改變語法的結合律。解決方案就是保留左遞迴的語法,不用自頂向下的方式分析。

消除左遞迴

參考關健young的部落格,左遞迴形式為 1 a a a vn,v 2 a b b a a b vn,v 稱其為左遞迴。其中可以採取修改左遞迴為右遞迴 a a 其中 非空,不以a打頭 可寫為 a a a a 即 a a 1 a 2 a m 1 2 n 其中,i 1 i m 均不為空,j 1 j n ...

消除左遞迴

first集的求法 對於文法g的任一符號串 x1x2 xn可按下列步驟構造其first 集合 1 置first 2 將first x1 中的一切非 符號加進first 3 若 first x1 將first x2 中的一切非 符號加進first 若 first x1 和first x2 將first...

消除左遞迴

1.將以下文法消除左遞迴,並分析符號串 i i i e e t t t t f f f e i 消除左遞迴 e t e e te t ft t ft f e i first集 first e first e first t first t first f follow集 follow e follo...