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,还好对这个内容重新看了一下,不然都没有发现我代码中的逻辑错误

文中有一些知识的解释是自己理解的,不一定对,学艺不精-_-||

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