将右递归转换为左递归的通用方法

时间:2015-12-16 12:50:29

标签: bison yacc

我最近在与Flex和Bison合作。我知道通常后者由于堆栈大小而无法正确递归。另一方面,大多数语法问题都可以通过正确的递归轻松解决。 AFAIK有通用算法将左递归改为右递归。有没有相反的方法?

这是一个简单的例子:

expression:
    number
  | expression operation number
  | expression operation openRound expression closeRound
  | openRound expression closeRound

您可以将号码和操作视为终端,因为它们与示例无关。

1 个答案:

答案 0 :(得分:0)

有些算法可以从语法中删除左或右递归(但不能同时删除)。这两种算法是彼此简单的镜像,因此您可以从算法中导出用于去除右递归的算法,以消除左递归。

但是,这些算法不保留解析树。如果你只是试图识别字符串是否在语言中,这无关紧要,但是当你真的想要解析字符串时,这并不是很有用,其中解析意味着“分析字符串的句法结构“。在这种情况下,生成不正确的解析树根本没有帮助。

此外,算法不一定保留LR(1)语言集合中的成员资格,因此使用LR(1)解析算法也可能不再可解析(或甚至可识别)结果语法。 / p>

<&意见GT; 在任何情况下,我都质疑“大多数......语法问题很容易用正确的递归解决”。实际上,大多数实际的解析问题都可以通过左递归更容易地解决,包括问题末尾的示例语法(左递归)。重新排列这样的语法是正确递归的,这样它可以由LL解析器处理,这可能是一个非常烦人的过程,其最终结果的可读性低于原始的左递归语法。 < /&意见GT;