LL和LR解析的主要优点和缺点是什么?


27

在使用一种编程语言构建解析器时,我会从中选择一种或另一种而赚到什么而又失去什么?


“ LL解析器”和“递归下降解析器”不是两个分开的东西吗?似乎可以使用RD解析器解析LL(k)语法,但这并不意味着LL 解析器与RD解析器相同。是这样吗 请参阅:stackoverflow.com/questions/1044600/...
XJI

@XiangJi:它们有很大的不同,因为每个LL语法都可以映射到RD解析器,但是倒数不一定成立(因为RD解析器的替代项是有序的,而LL语法是无序的)。
TimČas2015年

Answers:


42

我将对LL和LR解析进行比较,以得出许多标准:

复杂

LL在这里获胜,不负众望。您可以轻松地手写LL解析器。实际上,这通常是做得到的:Microsoft C#编译器是一个手写的递归下降解析器(在此处提供源代码,以查找Patrick Kristiansen发表的评论-博客文章也很有趣)。

LR解析使用一种违反直觉的方法来解析文本。它可以工作,但是我花了一些时间来思考它是如何工作的。因此,手工编写这样的解析器很困难:您或多或少会实现LR解析器生成器。

概论

LR在这里胜出:所有LL语言都是LR语言,但是LR语言比LL语言更多(如果可以用LL解析器解析,则语言是LL语言,如果可以用LL解析器解析,则语言是LR语言。 LR解析器)。

LL有许多麻烦之处,几乎在实现任何编程语言时都会打扰您。请参阅此处以获取概述。

有一些明确的语言不是LR语言,但是很少见。您几乎从未遇到过此类语言。但是,LALR确实存在一些问题。

LALR或多或少是LR解析器缩小表规模的一种手段。LR解析器的表通常可以增长很多。LALR解析器放弃了解析所有LR语言的能力,以换取较小的表。大多数LR解析器实际上使用LALR(尽管不是秘密地,您通常可以确切地找到它实现的内容)。

LALR可以抱怨移位减少和减少减少冲突。这是由表入侵引起的:它会将相似的条目“折叠”在一起,因为大多数条目为空,所以可以工作,但是当它们不为空时会产生冲突。这些错误是不自然的,很难理解,并且修复通常很奇怪。

编译器错误和错误恢复

LL在这里赢了。在LL解析中,通常很容易发出有用的编译器错误,尤其是在手写解析器中。您知道接下来的期望,因此,如果没有出现,您通常会知道出了什么问题以及最明智的错误是什么。

另外,在LL解析中,错误恢复要容易得多。如果输入解析不正确,您可以尝试略过一点,找出其余输入是否解析正确。例如,如果某些编程语句格式错误,则可以跳过并分析下一条语句,这样就可以捕获多个错误。

使用LR解析器,这要困难得多。您可以尝试扩充语法,以便它接受错误的输入并在出现问题的区域中打印错误,但这通常很难做到。以非LR(或非LALR)语法结尾的机会也会增加。

速度

速度与解析输入(LL或LR)的方式并不是真正的问题,而是结果代码的质量和表的使用(表可用于LL和LR)。因此,LL和LR在这方面具有可比性。

链接

是指向同时将LL和LR对比的站点的链接。查找底部附近的部分。

在这里您可以找到有关差异的对话。认真地看一下那里表达的意见,这不是一个坏主意,那里正在进行一场神圣的战争

有关更多信息,这里这里是我自己的两篇有关解析器的文章,尽管它们并不严格涉及LL和LR之间的对比。

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.