LL与LR解析器的局限性?

时间:2011-03-29 02:30:11

标签: programming-languages parser-generator ll lr

我知道LL与LR解析器的基本区别。我也知道GLR,SLR和LALR都是LR解析器的扩展。所以我的问题更详细的是......

给定一个LL(*)解析器和LR解析器的任何变体,是否有任何语言可以在一个而不是另一个中描述?或者更简单的是,是否存在任何无法表达的特征或属性?

作为一个具体的例子。如果我要使用LL(*)解析器创建一种语言,我是否会遇到我想要添加到我的语言中的所需功能/属性,这只能通过LR解析器实现(反之亦然)?

7 个答案:

答案 0 :(得分:10)

以下是一些观点,您可以将它们视为点和对位:

答案 1 :(得分:5)

不确定。 LL解析器无法处理左递归的任何语法。固定k的L(AL)R(k)解析器将无法解析LL( * )解析器可以处理的一些事情,因为k <*。

答案 2 :(得分:5)

您可能会在维基百科中发现这段有趣的内容,即LL(*)语法是LR(k)语法的子集: http://en.wikipedia.org/wiki/Context-free_grammar#Restrictions 因此,您可以使用LR解析方法解析更多语言。

答案 3 :(得分:4)

有些语法不能被“重写”由LL解析器解析,可以由LR解析器解析。一个例子:给出一个简单的语法来构造带有子句的术语:

S -> S - S | num

你显然在这里有左递归,LL解析器无法处理。要使这个语法可以通过LL解析,你必须消除左递归:

S -> num S'

S' -> - num S' | epsilon

现在你的LL解析器可以处理这个语法。但是当为4 - 2 -1这样的术语构建语法树时,在树上运行的深度优先搜索会给你4 - (2 - 1)= 3而不是(4 - 2) - 1 = 3正如你所料。

原因是,您必须在语法中使用左递归规则来处理左关联运算符(如substract)。但LL解析器无法处理左递归规则。

所以这里有一类LL无法处理的语言。

答案 4 :(得分:0)

LR解析器可以接受比LL更大的语言类。在LL(k)和LR(k)中,k表示它需要知道的前瞻符号的数量,因此它可以应用适当的生产/减少。 k越大,解析表就越大。因此k不仅限制LR解析器,它也限制LL解析器。 LR解析器可以接受更大类语言的原因是左递归在使用LL解析器时会出现问题。但这并不完全正确,因为直接递归是可解的,这意味着你可以将语法重写为LL语法。直接递归就像A - &gt; ABC。当您有间接递归时,您现在可能知道它的外观,那么您就遇到了问题。 LR解析器可以解决这个问题,因为它们以自下而上的方式生成解析树。你将不得不深入研究LR解析,看看究竟是为什么。但是,LR解析器并不都是强大的,它们也有局限性。有些语法很难消化,k因子也无济于事。对于这种语法,需要GLR解析器,它实际上模拟LR(k)解析器,但是当生成/减少模糊发生时使用回溯来分析整个解析空间。

答案 5 :(得分:0)

LR (1) 解析器比 LL (1) 识别更多的语法,因为它不需要我们重写语法来删除左递归和公因子。

然而,给定一个明确的语法,我们总是可以去除左递归和公因子,因此最终它们都可以解析相同的语言

如果有人对此有疑问,我挑战你给出一个明确的语法,即 LL(1) 无法解析而 LR(1) 可以,即无法重写以消除左递归和常见因素

答案 6 :(得分:-1)

LL解析理论上是O(n ^ 4),或者相当缓慢。 LR解析更快,O(n ^ 3)或非常慢。 https://en.wikipedia.org/wiki/Top-down_parsing

虽然我很乐意看到这方面的证据。