删除左递归

发布于 2024-08-29 07:07:00 字数 93 浏览 4 评论 0原文

下面的语法有左递归,

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅语花开 2024-09-05 07:07:00

是的,有一个一般过程,请参见wikipedia

E = TE'
E'= (e) | +TE'
T = FT'
T'= (e) | *FT'
F = a | b | c

// (e) is "epsilon" which is defined as the empty string

应该提到的是,这会从左到右改变 +* 的关联性。也就是说,之前 a + b + c 被解析为 (a + b) + c,现在被解析为 a + (b + c)

这不是加法和乘法的问题,但是例如减法和除法的问题。

维基百科文章有更多关于左递归删除过程及其复杂性的详细信息。

Yes, there is a general procedure, see e.g. wikipedia.

E = TE'
E'= (e) | +TE'
T = FT'
T'= (e) | *FT'
F = a | b | c

// (e) is "epsilon" which is defined as the empty string

It should be mentioned that this alters the associativity of + and * from left to right. That is, where before a + b + c was parsed as (a + b) + c, it is now parsed as a + (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.

凹づ凸ル 2024-09-05 07:07:00

例如,一般过程可以在 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'

夏尔 2024-09-05 07:07:00

正如其他人指出的那样,有一个用右递归替换左递归的通用过程。其他答案很好地展示了如何使用通用过程来删除给定语法中的左递归。

这是一个以特定于该语法的方式重构给定语法的解决方案。

E= T+E|T
T= F*T|F
F= a|b|c

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.

E= T+E|T
T= F*T|F
F= a|b|c
假装不在乎 2024-09-05 07:07:00

产生式

E = E+T
  | T
T = T*F
  | F
F = a|b|c

转到

E= T ('+' T)*
T= F ('*' F)*
F= a|b|c

​​“保持与使用 A(E,T) 处理第一个 E 析取项相同的处理”。新版本使用:

ret = T1;
while(set.more()) ret = A(ret, set.pop_front().T);

the production

E = E+T
  | T
T = T*F
  | F
F = a|b|c

goes to

E= T ('+' T)*
T= F ('*' F)*
F= a|b|c

To maintain the same processing where the fist E disjunct is processed with A(E,T). the new version uses:

ret = T1;
while(set.more()) ret = A(ret, set.pop_front().T);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文