LL和递归下降解析器之间的区别?


78

我最近正在尝试自学解析器(针对语言/无上下文语法)的工作方式,除了一件事之外,大多数解析器似乎都有意义。我特别关注LL(k)语法,这两个主要算法似乎是LL解析器(使用堆栈/解析表)和递归下降解析器(仅使用递归)。

据我所知,递归下降算法适用于所有LL(k)语法,甚至可能更多,而LL解析器适用于所有LL(k)语法。但是,递归下降解析器显然比LL解析器要简单得多(就像LL解析器比LR解析器一样简单)。

所以我的问题是,使用两种算法时可能遇到的优点/问题是什么?鉴于LL处理相同的语法集并且实现起来比较棘手,为什么人们会选择LL而不是递归血统?


嘿,能请您解释一下。您编写的似乎是LL解析器(使用堆栈/解析表)和递归下降解析器(仅使用递归)。此答案指出所有自上而下的解析器都是LL解析器。我很困惑
Max Koretskyi

2
@MaximKoretskyi绝对不正确。LL解析器是自上而下的解析器的子集。
Noldorin

谢谢,您可以发表您对我问题的回答吗?
Max Koretskyi

Answers:


104

LL通常是一种比递归下降更有效的解析技术。实际上,在最坏的情况下,幼稚的递归下降解析器实际上将是O(k ^ n)(其中n是输入大小)。一些技术(例如备忘录)(产生Packrat解析器)可以改善这一点,并扩展解析器接受的语法类别,但是总会有空间的取舍。LL解析器(据我所知)始终是线性时间。

另一方面,您的直觉是正确的,即递归下降解析器比LL可以处理更大的语法类别。递归下降可以处理任何LL(*)语法(即无限前行)以及一小部分歧义语法。这是因为递归下降实际上是PEG或Parser Expression Grammar(s)的直接编码实现。具体来说,析取运算符(a | b)不是可交换的,表示a | b不等于b | a。递归下降解析器将按顺序尝试每个替代方案。因此,如果a输入相匹配,它甚至会succede是否b 匹配的输入。这样可以实现经典的“最长匹配”歧义,例如晃来晃去else 简单地通过正确排序析取符即可解决该问题。

综上所述,可以使用递归下降实现LL(k)解析器,使其在线性时间内运行。这实际上是通过内联预测集来完成的,以便每个解析例程在恒定时间内确定给定输入的适当乘积。不幸的是,这种技术消除了整个语法类别的处理。一旦进入预测解析,悬空之else类的问题就不再那么容易解决了。

至于为什么选择LL而不是递归下降,这主要是效率和可维护性的问题。递归下降解析器的实现明显更容易,但是它们通常更难维护,因为它们表示的语法不存在任何声明性形式。大多数非平凡的解析器用例都使用解析器生成器,例如ANTLR或Bison。有了这样的工具,算法是直接编码的递归下降还是表驱动的LL(k)确实无关紧要。

有兴趣的是,还值得研究recursive-ascent,它是一种以递归下降方式直接编码但可以处理任何LALR语法的解析算法。我还将研究解析器组合器,这是将递归下降解析器组合在一起的一种功能方式。


2
我非常希望得到答复!:)感谢您提供的所有信息(包括最后一点,我什至都不知道)。在我理解您在此答案中提出的所有概念之前,可能还需要阅读一些内容,但是您当然已经回答了我的问题,并指出了正确的方向,以供进一步研究。我现在主要模糊的是PEG与递归下降解析器的关系,以及解析器组合器如何准确地组合各种解析器。如果您能澄清这两者之一,我将不胜感激。
Noldorin

6
预测集:这实际上取决于所使用的策略。如果依靠这些预测集并且不执行任何回溯,则语法的类别恰好是LL(k),其中k是用于计算预测集的超前量。但是,通过在RD中内联预测集而无需完全消除回溯的情况下,可以获得预测分析的很多好处。这样,解析器就可以接受通常由RD处理的所有语法,但是平均情况更快。不幸的是,这种解析器的最坏情况仍然是指数级的。
Daniel Spiewak 09年

5
大多数递归下降解析器(甚至是手写递归解析器)都将使用内联预测集来限制替换项,从而在不限制灵活性的情况下限制回溯。最终的结果是一个解析器,除了最病理的语法外,它几乎对所有事物都是线性时间,并且仍然接受整个PEG类。
Daniel Spiewak 09年

4
好东西。不过,有个提要:“大多数非平凡的用例都是在某种解析器生成器中实现的……”。这不是真的。最广泛使用的编译器和IDE(C#,VB,Visual C ++和GCC是很好的示例)使用手写解析器。这些可以说是最不平凡的用途。
Scott Wisniewski

3
@DanielSpiewak我知道你在几年前发布了该评论,但即使在那时也错了;)GCC在C解析器中一直使用bison直到3.x,但在我可能的范围内,2008年我切换到了手写递归下降解析器。从此告诉gcc.gnu.org/wiki/New_C_Parser
Morten Jensen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.