CFG文法及左遞歸的消除——編譯原理

爲了寫實驗,重新回顧一下CFG和左遞歸

1、上下文無關文法

(1) 上下文無關文法(CFG,Context Free Grammar)

顧名思義就是與上下文無關,不考慮上下文的語境,可以將它單獨拿出進行分析、解釋。

(2)上下文無關文法包含的四個部分

一組非終結符(VN一組終結符號(VT、一組產生式(P)、一個開始符號(S)

例:G1=(VN,VT,P,S)
其中:VN={E},VT={i,+,*},S=E,P={E->i,E->E+E,E->E*E}

如果產生式有共同的左部,如α\alpha->β\betaα\alpha->γ\gamma,可簡寫爲α\alpha->β\beta|γ\gamma,其中β\betaγ\gamma分別稱爲α\alpha的一個候選式

將上面的產生式寫成E->i|E+E|E*E的形式,最後可轉換爲E->i+i|i*i

  1. 終結符(Terminator):是組成語言的基本符號。顧名思義就是到了結尾的符號,是不可再分的具有獨立意義的基本符號。(emm,說白了就是不能繼續進行替換的符號,如例中最後的形式,i即爲終結符)
  2. 非終結符(Nonterminal):用來表示語法範疇,如表達式、函數。(還可以繼續進行替換的符號,如最後的E->i+i,可以用E表示加法和乘法)
  3. 產生式(production):所謂產生式是定義語法範疇的一種書寫規則。也被稱爲重寫規則,可以用一個符號串替換另一個符號串。(如E->i,E->E+E;E可以用i和E+E進行替換)
  4. 開始符號(start):特別的非終結符,代表所定義的語言中的最終的語法範疇。

(3)上下文無關文法的定義

文法G是一個四元組,G=(VN,VT,P,S),其中VN,VT分別是非空有限的非終結符號集合終結符號集,VN \bigcap VT = \emptyset,P是產生式集,S\inVN稱爲文法的識別符號或開始符號。開始符號S必須在某個產生式的左部出現一次。

2、遞歸

(1)遞歸產生式:

形如:
A->xAy, x,y\in(VT\bigcupVN)*,A\inV~N
的產生式稱爲遞歸產生式

(2)左遞歸產生式

  1. 直接左遞歸

在遞歸產生式的基礎上,若x = ε\varepsilon(即候選式的第一個字符與開始符號相同,進行替換時,右邊確定爲y,左邊則是一個A的遞歸),有
A->Ay
這個稱爲直接遞歸產生式

  1. 間接左遞歸

間接左遞歸:每一條產生式都不是直接左遞歸,但經過多次推導可以得出直接左遞歸,則爲間接左遞歸
例:
A->Bb
B->A|a
替換後:A->Ab|ab

(3)右遞歸產生式

  1. 直接右遞歸

在遞歸產生式的基礎上,若y = ε\varepsilon(即候選式的最後一個字符與開始符號相同,進行替換時,左邊確定爲x,右邊則是一個A的遞歸),有
A->xA
這個稱爲直接右遞歸產生式

  1. 間接右遞歸

3、消除直接左遞歸

(1)方法
直接改寫法

U -> Ux | y
U -> yU’
U’ -> xU’ | ε\varepsilon

(2)例

A -> [B
B -> X] | BA
X -> Xa|Xb|a|b

消除後結果

A -> [B
B -> X]B’
B’ -> AB’ | ε\varepsilon
X -> aX’ | bX’
X’ -> aX’ | bX’ | ε\varepsilon

4、消除間接左遞歸

(1)方法

1、將文法G的所有非終結符整理成某一順序U1,U2…,Un
2、開始符號從後往前走

for( i : 1 到 n)

for(j : 1 到 i - 1)

將產生式Ui -> Ujα1 | Ujα2…替換爲
Ui -> β1α1 | β1α2 | β2α1 | β2α2 | … | βmα2
(其中Uj -> β1 | β2 | … | βm

(2)例

A -> Bcd
B -> Ce | f
C -> Ab | c

分析:

開始符號爲A、B;從後往前,故U1 = C,U2 = B,U3=A
i = 2,j = 1時:

U2 -> U1α
將B -> Ce | f 替換爲 B -> Abe | ce | f
U1爲C,α1Ab,α2c; 含有開始符號除去後爲α
U2爲B,β1Ce,β2f; Uj的候選式即爲β
將α與β組合 再加上 不含U1的部分(f),即Abe | ce | f

B -> Abe | ce | f
i = 3,j = 2

U3 -> U2α
將A -> Bcd 替換爲 A -> Abecd | cecd | fcd
U3爲A,α爲Bcd
U2爲B,β1Abe,β2ce,β2f
將α與β組合,即Abecd | cecd | fcd

消除後結果

A -> Abecd | cecd | fcd

5、代碼實現

[編譯原理-左遞歸的消除-QT/C++]()

6、結

emm,還好對這個內容重新看了一下,不然都沒有發現我代碼中的邏輯錯誤

文中有一些知識的解釋是自己理解的,不一定對,學藝不精-_-||

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