逐步消除此间接左递归

时间:2013-04-14 14:02:55

标签: parsing context-free-grammar left-recursion

我已经看到this algorithm应该能够用来删除所有左递归。 然而,我遇到了这个特殊语法的问题:

A -> Cd
B -> Ce
C -> A | B | f

无论我尝试什么,我最终都会循环或使用仍然间接留下递归的语法。

在此语法上正确实施this algorithm的步骤是什么?

2 个答案:

答案 0 :(得分:26)

规则是你首先为非终端建立某种顺序,然后找到间接递归发生的所有路径。

在这种情况下,订单将是A< B< C和非终端C的递归的可能路径将是

C=> A => Cd

C=> B => Ce

因此C的新规则将是

C=> Cd | Ce | f

现在你可以简单地删除直接左递归:

C=> fC'
C'=> dC' | eC' | eps

,得到的非递归语法将是:

A => Cd
B => Ce
C => fC'
C' => dC' | eC' | eps

答案 1 :(得分:8)

已经弄清楚了。

我的困惑在于,按此顺序,算法似乎什么都不做,所以我认为这一定是错的,并且开始替换A - >第一次迭代中的Cd(忽略j不能超越i)进入无限循环。

1)通过重新排序规则:

C -> A | B | f 
A -> Cd
B -> Ce

2)替换A中的C - >镉

C -> A | B | f 
A -> Ad | Bd | fd
B -> Ce

3)B尚未在j的范围内,所以请保留并替换A

的直接左递归
C -> A | B | f 
A -> BdA' | fdA'
A'-> dA' | epsylon
B -> Ce

4)替换B中的C - >铈

C -> A | B | f 
A -> BdA' | fdA'
A'-> dA' | epsylon
B -> Ae | Be | fe

5)还没完成!还需要更换新规则B - > Ae(A的产生在j的范围内)

C -> A | B | f 
A -> BdA' | fdA'
A'-> dA' | epsylon
B -> BdA'e | fdA'e | Be | fe

6)在B

的作品中替换直接左递归
C -> A | B | f 
A -> BdA' | fdA'
A'-> dA' | epsylon
B -> fdA'eB' | feB'
B'-> dA'eB' | eB' | epsylon

哇噢!左递归免费语法!