it-swarm.cn

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

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

29
Maniero

我将对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对比的站点的链接。查找底部附近的部分。

这里 您可以找到有关差异的对话。批判地看一下那里发表的意见,这不是一个坏主意,那里有一些 神圣之战 正在进行。

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

44
Alex ten Brink