我最近在与Flex和Bison合作。我知道通常后者由于堆栈大小而无法正确递归。另一方面,大多数语法问题都可以通过正确的递归轻松解决。 AFAIK有通用算法将左递归改为右递归。有没有相反的方法?
这是一个简单的例子:
expression:
number
| expression operation number
| expression operation openRound expression closeRound
| openRound expression closeRound
您可以将号码和操作视为终端,因为它们与示例无关。
答案 0 :(得分:0)
有些算法可以从语法中删除左或右递归(但不能同时删除)。这两种算法是彼此简单的镜像,因此您可以从算法中导出用于去除右递归的算法,以消除左递归。
但是,这些算法不保留解析树。如果你只是试图识别字符串是否在语言中,这无关紧要,但是当你真的想要解析字符串时,这并不是很有用,其中解析意味着“分析字符串的句法结构“。在这种情况下,生成不正确的解析树根本没有帮助。
此外,算法不一定保留LR(1)语言集合中的成员资格,因此使用LR(1)解析算法也可能不再可解析(或甚至可识别)结果语法。 / p>
<&意见GT; 在任何情况下,我都质疑“大多数......语法问题很容易用正确的递归解决”。实际上,大多数实际的解析问题都可以通过左递归更容易地解决,包括问题末尾的示例语法(左递归)。重新排列这样的语法是正确递归的,这样它可以由LL解析器处理,这可能是一个非常烦人的过程,其最终结果的可读性低于原始的左递归语法。 < /&意见GT;