爲了寫實驗,重新回顧一下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}
如果產生式有共同的左部,如->,->,可簡寫爲->|,其中,分別稱爲的一個候選式
將上面的產生式寫成E->i|E+E|E*E
的形式,最後可轉換爲E->i+i|i*i
- 終結符(Terminator):是組成語言的基本符號。顧名思義就是到了結尾的符號,是不可再分的具有獨立意義的基本符號。(emm,說白了就是不能繼續進行替換的符號,如例中最後的形式,i即爲終結符)
- 非終結符(Nonterminal):用來表示語法範疇,如表達式、函數。(還可以繼續進行替換的符號,如最後的E->i+i,可以用E表示加法和乘法)
- 產生式(production):所謂產生式是定義語法範疇的一種書寫規則。也被稱爲重寫規則,可以用一個符號串替換另一個符號串。(如E->i,E->E+E;E可以用i和E+E進行替換)
- 開始符號(start):特別的非終結符,代表所定義的語言中的最終的語法範疇。
(3)上下文無關文法的定義
文法G是一個四元組,G=(VN,VT,P,S),其中VN,VT分別是非空有限的非終結符號集合終結符號集,VN VT = ,P是產生式集,SVN稱爲文法的識別符號或開始符號。開始符號S必須在某個產生式的左部出現一次。
2、遞歸
(1)遞歸產生式:
形如:
A->xAy, x,y(VTVN)*,AV~N
的產生式稱爲遞歸產生式
(2)左遞歸產生式
- 直接左遞歸
在遞歸產生式的基礎上,若x = (即候選式的第一個字符與開始符號相同,進行替換時,右邊確定爲y,左邊則是一個A的遞歸),有
A->Ay
這個稱爲直接遞歸產生式
- 間接左遞歸
間接左遞歸:每一條產生式都不是直接左遞歸,但經過多次推導可以得出直接左遞歸,則爲間接左遞歸
例:
A->Bb
B->A|a
替換後:A->Ab|ab
(3)右遞歸產生式
- 直接右遞歸
在遞歸產生式的基礎上,若y = (即候選式的最後一個字符與開始符號相同,進行替換時,左邊確定爲x,右邊則是一個A的遞歸),有
A->xA
這個稱爲直接右遞歸產生式
- 間接右遞歸
3、消除直接左遞歸
(1)方法
直接改寫法
U -> Ux | y
U -> yU’
U’ -> xU’ |
(2)例
A -> [B
B -> X] | BA
X -> Xa|Xb|a|b
消除後結果
A -> [B
B -> X]B’
B’ -> AB’ |
X -> aX’ | bX’
X’ -> aX’ | bX’ |
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,α1爲Ab
,α2爲c
; 含有開始符號除去後爲α
U2爲B,β1爲Ce
,β2爲f
; Uj的候選式即爲β
將α與β組合 再加上 不含U1的部分(f),即Abe | ce | f
B -> Abe | ce | f
i = 3,j = 2U3 -> U2α
將A -> Bcd 替換爲 A -> Abecd | cecd | fcd
U3爲A,α爲Bcd
;
U2爲B,β1爲Abe
,β2爲ce
,β2爲f
;
將α與β組合,即Abecd | cecd | fcd
消除後結果
A -> Abecd | cecd | fcd
5、代碼實現
[編譯原理-左遞歸的消除-QT/C++]()
6、結
emm,還好對這個內容重新看了一下,不然都沒有發現我代碼中的邏輯錯誤
文中有一些知識的解釋是自己理解的,不一定對,學藝不精-_-||