【问题标题】:Bypassing left recursion with right-to-left parser使用从右到左的解析器绕过左递归
【发布时间】:2015-12-19 20:07:10
【问题描述】:

我正在为我的 OOP 课程做一个项目。部分任务是为非常简单的语法开发解析器。据我了解,目前最简单的手动实现解析器是递归下降解析器。

但是,我正在解析的语言的所有运算符本质上都是左关联的。据我所知,处理由左关联性强制执行的左递归的最佳方法是使用 LR 解析器。

我的想法是从右到左解析标记,我相信这应该使我能够将左关联规则重写为右关联规则。

这会有效吗?如果无效,为什么不呢?

【问题讨论】:

  • 到目前为止,最容易编写的解析器是您只需指定(无上下文)语法的解析器,解析器生成器工具会处理所有问题。我在 GLR 解析器方面拥有非常好的经验。 (基于 Earley 的解析器也不错,但由于速度问题,一般不适合生产)。
  • 我同意。虽然我对这个项目的解析器生成器(YACC/Bison)有一些经验,但我更喜欢使用手写解析器。首先,我什至不认为我被允许使用外部库,并且使用 Bison 或类似的东西可能需要这样做。其次,我想了解更多关于解析和编译器设计的一般知识,所以我想借此机会这样做,特别是因为我需要解析的语法非常简单,所以这是学习新东西的完美情况。无论如何,我相信在这种情况下递归下降解析器是最简单的解决方案。
  • 好的。然后查看我关于如何编写递归下降解析器的 SO 答案。这些很容易处理左递归。见stackoverflow.com/questions/2245962/…

标签: parsing recursion


【解决方案1】:

如果您愿意,您可以这样做,但这不一定能解决您的所有问题。如果您熟悉 LL 或 LR 解析器,那么有相应的版本可以从右到左工作,称为 RR 和 RL 解析器,它们的工作方式与 LL 或 LR 解析器在相反方向上的扫描非常相似。因此,它们与原始的 LL 或 LR 解析算法有相似的弱点,因此虽然这可能对您有所帮助,但实际上可能无法解决任何问题。

作为替代方案,您可以尝试重写语法以查看是否可以直接编码优先级和关联性。您还可以根据语法考虑使用优先解析算法,例如 Dijkstra 的 shunting-yard 算法。您还可以考虑使用带有回溯的递归下降解析器。最后,您可以使用 Earley 解析器之类的东西,它可以处理任何语法并且编码起来并不难。

【讨论】:

  • 如果我没记错的话,我正在尝试编写的递归下降解析器相当于 RR 解析器。所以考虑到我的语法中没有右结合表达式,没有陷入无限递归的危险。请详细说明这一点,我想知道我的观点是否以某种方式倾斜。另外,感谢您提出的替代解决方案,我一定会研究您提到的算法和技术。
  • 没有看到您的语法,我无法评论从右到左的解析器是否可以工作。但是,如果您的语法没有正确的递归,并且同一个非终结符的两个产生式没有共同的后缀,那么您的策略可能会奏效。我主要是警告不要认为 RR 解析器会处理 LL 解析器不会处理的任何事情。
【解决方案2】:

很好的洞察力——事实证明,这对于解决左递归问题非常有效,但是您还必须自下而上解析,而不仅仅是从右到左。我为此发表了一份预印本。

Pika解析:逆向解析解决左递归和错误恢复问题

https://arxiv.org/abs/2005.06444

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-03
    • 1970-01-01
    • 2014-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-17
    • 1970-01-01
    相关资源
    最近更新 更多