【编译原理】文法左递归的消除

在自上而下分析中,左递归文法是一定需要改写的。对于简单的左递归文法,例如那种只含有直接左递归,一眼可以看出左递归在哪里的文法,我们可以直接使用下面的公式来消除左递归:

【下图引用自中南大学徐德智老师的编译原理2020年授课PPT】

在这里插入图片描述

直接左递归.

下面给出两个文法的例子:

G[S]:
S→S*a|a|(S)

G[E]:
E→E+M|E^|M
M→PbM|P
P→cEd|#

不难发现这两个文法中都只含有直接左递归,G[S]中的递归产生式为S→S*a,G[E]中的递归产生式为E→E+M以及E→E^.这类文法的直接左递归消除可以直接使用上述公式,消除之后的无直接左递归文法如下:

G[S]:
S→aT|(S)T
T→*aT|ε

G[E]:
E→MT
T→+MT|^T|ε
M→PbM|P
P→cEd|#

复杂左递归.

但如果遇到文法不是直接左递归的,它可能是间接左递归的,或者二者兼具,我们就无法直接使用上述公式来消除其左递归。但我们可以证明,对于一个不含有P→P这样的"回路产生式"以及P→ε这样的空产生式的文法,我们是一定可以消除其左递归的。我们给出两个这样的文法示例:

G[S]:
S→Qc|c
Q→Rb|b
R→Sa|a

G[L]:
L→La|Tb|c
T→L+|T*|f

对于文法G[S],其每一个产生式都不含有直接左递归,但如果细细察看,它是存在这样的情况的:S→Qc→Rbc→Sabc,也就是间接左递归。对于这样的文法,我们如何消除其左递归。我们先以G[S]为例,叙述其具体消除过程,最后给出普适算法。

  1. 首先给文法的所有非终结符,以任意次序标号,从左向右考察这些非终结符,对于序号为i的非终结符,我们检测它是否有形如P i _i →P i k _{i-k} α这样的产生式,如果有就将P i k _{i-k} 的出现用其产生式代替。然后消除直接左递归(如果并没有直接左递归就什么也不做).
  2. 对于G[S]中的非终结符,S、Q、R我们规定一个次序,不妨就是S、Q、R这一次序。首先考察S,它并没有前置位的非终结符,所以我们进入直接左递归消除阶段,发现也没有直接左递归,所以对于S的产生式什么也不做;
  3. 考察Q,它的前置位非终结符是S,但显然Q没有形如Q→Sα这样的产生式,所以进入消除直接左递归的阶段,发现也没有直接左递归,所以对于Q的产生式我们什么也不做;
  4. 考察R,它的前置位非终结符是S和Q。依旧是从左向右考察,第一次扫描是S,我们发现有R→Sa这一产生式,所以执行替换,替换后的产生式为R→Qca|ca|a,进入消除直接左递归阶段,发现并没有事情可做;于是进入下一次扫描,这次的非终结符为Q,现在的R产生式中已经有了R→Qca这一产生式,所以也需要执行替换,替换后的产生式为R→Rbca|bca|ca|a,接下来进入消除左递归阶段,最终我们得到的文法如下所示:
G[S]:
S→Qc|c
Q→Rb|b
R→bcaT|caT|aT
T→bcaT|ε

实际上我们也可以采取另外的次序,例如我们标记顺序为R、Q、S,经过同样的步骤,得到的文法为:

G[S]:
S→abcT|bcT|cT
T→abcT|ε
Q→Rb|b
R→Sa|a

并且我们发现从开始符号S出发,永远也不会到达Q和R,所以关于Q和R的产生式完全多余.
最终为:

G[S]:
S→abcT|bcT|cT
T→abcT|ε

针对第二个示例文法,其中既有直接左递归,又存在间接左递归:

G[L]:
L→La|Tb|c
T→L+|T*|f
  1. 我们不妨标记次序为T、L;首先考察T,它并没有前置位非终结符,所以直接进行直接左递归的消除,消除之后的T产生式如下:
T→L+M|fM
M→*M|ε
  1. 考察非终结符L,其前置位非终结符为T,并且L产生式中有L→Tb,所以需要进行替换,替换后的L产生式如下:
L→La|L+Mb|fMb|c

而后进入左递归消除阶段,消除直接左递归后的L产生式如下:

L→fMbN|cN
N→+MbN|aN|ε
  1. 所以最终得到的无左递归文法如下所示:
G[L]:
L→fMbN|cN
N→+MbN|aN|ε
T→L+M|fM
M→*M|ε

显然我们发现,从起始符号L出发,是无法到达非终结符T的,所以关于T的产生式是多余的.
最终:

G[L]:
L→fMbN|cN
N→+MbN|aN|ε
M→*M|ε

实际上我们也可以规定顺序为L、T,但那样会导致T不是多余的非终结符,而L作为起始符号又不可能删去,从而产生式的数量较多。通过这两个例子,我们也不难看出,如果想要将产生式的数量减少,最好是将起始符号的次序向后排,先剩余的非终结符进行改造,最终对于起始符号利用已经改造了一部分的文法产生式进行操作。

普适左递归消除算法.

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44246009/article/details/107035944
今日推荐