繁体   English   中英

消除左递归

[英]Eliminating Left Recursion

所以我有一些语法对于自上而下的解析器不起作用,因为它有递归:

L::= A a | B b
A::= L b | a a
B::= b B b | b a

因此,为了解决此问题,我必须删除左递归。 为此,我做了一些类似替代的事情:

L::= A a | B b
A::= A a b | B b b | a a (I plugged in the possible values of "L")

然后A转向(我相信):

A::= a a A' | B b b
A'::= a b A' | ε

我可以肯定的是,我是正确的(尽管我不会,但也不会感到惊讶)。 我现在正在努力的地方是从“ B bb”中删除左递归。 我已经尝试了很多方法,但我认为其中任何一个都行不通。 这似乎是最合逻辑的,但也很丑陋(因此说这可能是错误的)。 从操作B :: = b B b | BA

B::= b B b | b a
B::= b B' (they both start with b, so maybe i can pull it out?)
B'::= B b | a
B'::= b B' b | a (substituted B's value in)
B'::= b B" | a
B"::= b B" |a B" | ε

所以我想证明最终的B是什么:

B::= b B'
B'::= b B" | a
B"::= b B" | a B" | ε

这似乎太丑陋了以至于不正确。 特别是因为我必须将其插入我创建的新“ A”终端中。

有人可以帮我吗? 不知道我是否要按照正确的方式进行操作。 我应该能够在以后创建LL(1)解析表(应该可以自己完成该部分)。

谢谢。

在试图从左侧扩展非终结符的解析器中,如果某个非终结符可以扩展为自身位于左侧的字符串,则解析器可以永远扩展该非终结符,而无需实际解析任何内容。 这是左递归。 另一方面,如果一个非末端扩展为左侧带有一些不同非末端的字符串,那也很好,只要没有扩展链产生一个原始非末端位于左侧的字符串即可。 同样,只要非终结符不在扩展中一直向右移动,也可以,只要它们不一直向左移动即可。

tl; dr B bbb B b没错。 您已删除了所有剩余的递归。 您不需要继续前进。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM