Parsing 递归上升解析器是如何工作的?

Parsing 递归上升解析器是如何工作的?,parsing,recursion,Parsing,Recursion,递归上升解析器是如何工作的?我自己写了一个递归下降解析器,但我不太了解LR解析器。我所做的只是增加了我的困惑 另一个问题是为什么递归上升解析器没有比基于表的解析器使用得更多。递归上升解析器的总体性能似乎更高。我个人很难理解函数调用是如何更快的——更不用说比查表更快了。我怀疑,与lexer/解析器必须做的其他事情(主要是读取和标记文件)相比,甚至“显著更快”都是微不足道的。我看了维基百科页面,但没有看参考资料;作者是否真的描述了一个完整的lexer/解析器 我更感兴趣的是表驱动解析器相对于递归下降

递归上升解析器是如何工作的?我自己写了一个递归下降解析器,但我不太了解LR解析器。我所做的只是增加了我的困惑


另一个问题是为什么递归上升解析器没有比基于表的解析器使用得更多。递归上升解析器的总体性能似乎更高。

我个人很难理解函数调用是如何更快的——更不用说比查表更快了。我怀疑,与lexer/解析器必须做的其他事情(主要是读取和标记文件)相比,甚至“显著更快”都是微不足道的。我看了维基百科页面,但没有看参考资料;作者是否真的描述了一个完整的lexer/解析器

我更感兴趣的是表驱动解析器相对于递归下降的衰落。我来自C语言背景,其中yacc(或同等)是首选的解析器生成器。当我转向Java时,我发现了一个表驱动实现(JavaCup)和几个递归下降实现(JavaCC、ANTLR)

我怀疑答案与“为什么用Java代替C”的答案类似:执行速度不如开发速度重要。正如Wikipedia文章中提到的,表驱动解析器几乎不可能从代码中理解(回到我使用它们的时候,我可以跟随它们的动作,但永远无法从解析器中重建语法)。相比之下,递归下降是非常直观的(这无疑是它比表驱动早20年的原因)。

该理论很好地解释了LR解析器的工作原理。如果我记得清楚的话,你也可以在那里读到关于他们的资料。维基百科上的文章(至少是导言)是不对的。它们是由Donald Knuth创建的,他在《计算机编程艺术》第5卷中对此进行了解释。如果你懂西班牙语,这里有我贴的一份完整的书单。也不是所有的书都是西班牙语的

在理解它们的工作原理之前,您必须先了解一些概念,如first、follows和lookahead。另外,我真的建议您在尝试理解LR(上升)解析器之前先理解LL(下降)解析器背后的概念

有一系列解析器LR,特别是LR(K)、SLR(K)和LALR(K),其中K是它们需要工作的前瞻数。Yacc支持LALR(1)解析器,但您可以进行调整,而不是基于理论,以使其与更强大的语法一起工作


关于性能,这取决于所分析的语法。它们以线性时间执行,但它们需要多少空间取决于为最终解析器构建多少状态

维基百科关于递归上升解析的文章引用了关于该主题的原始论文(“极快LR解析”)。略读那篇论文为我澄清了一些事情。我注意到的事情:

  • 本文讨论了汇编代码的生成。我想知道,如果您生成的是C或Java代码,您是否可以执行与它们相同的操作;请参阅第4节和第5节“错误恢复”和“堆栈溢出检查”。(我并不是在试图捏造他们的技术——这可能会很好——只是说这是你在提交之前可能需要研究的东西。)

  • 他们将递归上升工具与自己的表驱动解析器进行比较。从结果部分的描述来看,表驱动解析器似乎是“完全解释的”;它不需要任何自定义生成的代码。我想知道是否有一种中间立场,即总体结构仍然是表驱动的,但您可以为某些操作生成自定义代码以加快速度

  • 维基百科页面引用的论文:

    • “极快LR解析”(1986年)
    另一篇关于使用代码生成代替表解释的论文:

    • “非常快速的YACC兼容解析器(非常省力)”(1999年)
    另外,请注意,递归下降解析并不是解析基于LL语法的语言的最快方法:


    递归下降比表驱动的LR解析器慢。我想知道递归上升是一个完全不同的野兽。是的,根据文章,递归上升有内联函数调用来表示状态机,而不是一个变量和表。正如我在第一段中所说的,我并不认为它更快,特别是在解析器的使用环境中。但我也提出了一个更重要的观点:解析器实现的原始速度很少重要。我认为基于方法的解析器(尤其是递归下降)的主要卖点是可调试性。走电话要比坐在桌子上容易得多。然而,我见过一些调试器,它们将映射移回到语法并使其更具可读性。+1我一直在想同样的事情。递归下降解析器很容易理解,但很难正确使用。LR解析器很容易用生成器(比如YACC)编写,但我从未真正理解它是如何“在引擎盖下”工作的。快乐的“好问题”徽章:)第5卷还有几年呢!充其量。我希望我能在2020年或任何时候回到这一页,对这一评论发笑。@DariusBacon——欢迎来到2020:)