删除左递归
下面的语法有左递归,
E= E+T|T
T= T*F|F
F= a|b|c
如何去掉呢?有没有一般程序?
The following grammar has left recursion
E= E+T|T
T= T*F|F
F= a|b|c
How to remove it? Is there any general procedure for it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的,有一个一般过程,请参见wikipedia。
应该提到的是,这会从左到右改变
+
和*
的关联性。也就是说,之前a + b + c
被解析为(a + b) + c
,现在被解析为a + (b + c)
。这不是加法和乘法的问题,但是例如减法和除法的问题。
维基百科文章有更多关于左递归删除过程及其复杂性的详细信息。
Yes, there is a general procedure, see e.g. wikipedia.
It should be mentioned that this alters the associativity of
+
and*
from left to right. That is, where beforea + b + c
was parsed as(a + b) + c
, it is now parsed asa + (b + c)
.This is not a problem for addition and multiplication, but it would be a problem for subtraction and division, for example.
Wikipedia article has more detail on the left-recursion removal procedure and its intricacies.
例如,一般过程可以在 Wikipedia 中找到。我将演示
E = E+T|T
:E
是左递归非终结符。+T
是非空序列 (alpha)。T
是不以 E 开头的序列(测试版)。我们为“其余”创建一个新的非终结符,即。非空序列。这处理递归。
E' = epsilon|+TE'
我们修改原始规则以使用新的非终结符来处理递归。
E = TE'
The general procedure is found at Wikipedia, for example. I'll demonstrate for
E = E+T|T
:E
is the left-recursive non-terminal.+T
is the non-null sequence (alpha).T
is the sequence which doesn't start with E (beta).We create a new nonterminal for the "rest", ie. the non-null sequence. This handles the recursion.
E' = epsilon|+TE'
And we modify the original rule to use the new nonterminal to handle the recursion.
E = TE'
正如其他人指出的那样,有一个用右递归替换左递归的通用过程。其他答案很好地展示了如何使用通用过程来删除给定语法中的左递归。
这是一个以特定于该语法的方式重构给定语法的解决方案。
As others have pointed out, there is a general procedure for replacing left recursion with right recursion. The other answers show well how to use that general procedure to remove the left recursion in the given grammar.
Here is a solution that restructures the given grammar in a way that is specific for that grammar.
产生式
转到
“保持与使用
A(E,T)
处理第一个 E 析取项相同的处理”。新版本使用:the production
goes to
To maintain the same processing where the fist E disjunct is processed with
A(E,T)
. the new version uses: