LALR和LR解析有什么区别?

我理解LR和LALR都是自下而上的解析算法,但两者之间有什么区别?

LR(0),LALR(1)和LR(1)解析有什么区别?如何判断语法是LR(0),LALR(1)还是LR(1)?

在高水平上,LR(0),LALR(1)和LR(1)之间的差异如下:

> LALR(1)解析器是LR(0)解析器的“升级版”,可以跟踪更准确的信息来消除语法的歧义。一个LR(1)解析器是一个显着更强大的解析器,跟踪比LALR(1)解析器更精确的信息。
> LALR(1)解析器是大于LR(0)解析器的常数因子,LR(1)解析器通常大于LALR(1)解析器。
>可以使用LALR(1)解析器解析可以用LR(0)解析器解析的任何语法,并且可以用LR(1)解析器解析可以用LALR(1)解析器解析的任何语法。有LALR(1)但不是LR(0)和LR(1)但不是LALR(1)的语法。

更正式地说,LR(k)解析器是一个自下而上的解析器,通过将一堆终端保持为非终结符来工作。解析器由有限自动机控制,该自动机基于解析器的当前状态和下一个输入的k个令牌来确定是否将新令牌移动到堆栈上,或通过反向应用生产来减少堆栈的顶部符号。

为了跟踪足够的信息来确定是否移动或减少,LR(k)解析器的每个状态都对应于“配置集”,一组用以下信息注释的生产:

>到目前为止,已经看到了多少生产
>生产完成后所需的令牌(前瞻)

这些信息中的第一个用于确定解析器是否可能需要执行缩减 – 如果当前状态中的任何一个都没有完成,则没有理由进行减少。这些信息中的第二条在进行缩减以确定是否应执行缩减时使用。当决定是否减少时,LR(k)解析器查看输入流的下一个k个令牌。如果它们与前瞻性令牌匹配,解析器将减少,否则解析器什么也不做。

当解析器在给定状态下应该做什么时,会在LR(k)解析器中出现问题。当解析器处于生产完成的状态时,出现一种类型的冲突,即转移/减少冲突,但该生产冲突的前瞻性符号也被该状态下的另一个未完成的生产使用。这意味着解析器无法判断是否执行还原。第二种类型的冲突是减少/减少冲突,解析器知道它必须进行减少,但是可以进行两次或更多次的减少,并且无法确定哪个要做。

直观地,随着k变得越来越大,解析器具有越来越多的精确信息,以确定何时移位以及何时减少。例如,如果一个语法不是LR(0),那么解析器可能有一个状态,在这个状态下,没有前瞻性,所以它无法确定是移动还是减少。然而,这个语法可能仍然是LR(1),因为给了一个额外的前瞻性的标记,它可能能够认识到它应该是肯定的转移,而不是减少或绝对减少而不是转移。

LR(k)解析器的问题是随着k越来越大,状态数可以指数增加。 LR(k)解析器中的前瞻是通过在解析器中构建越来越多的状态来对应于生产和前瞻的不同组合来处理的,因此可能的前瞻数量也随着状态数量的增加而增加。因此,LR(1)解析器通常太大而不实用,LR(2)或更大)在实践中几乎闻所未闻。

LALR(1)被发明为LR(0)解析器的空间效率和LR(1)解析器的表现力之间的妥协。有几种方法来考虑一个LALR(1)解析器是什么。最初,LALR(1)解析器被指定为将LR(1)自动机转换为较小自动机的转换。虽然LR(1)解析器可能具有比LR(0)自动机更多的状态,但唯一的区别是LR(1)解析器可以在LR(0)自动机中具有任何特定状态的多个副本,每个注释为不同的前瞻信息。可以通过从LR(1)解析器开始,然后将具有相同“核心”(生成集合及其位置)的所有状态组合在一起,然后将所有前瞻信息聚合在一起,从而形成LALR(1)解析器。这导致一个解析器具有与LR(0)解析器相同数量的状态,但保留了一些有关前瞻性的信息,以帮助避免LR冲突。

LALR(1)语法的另一种观点使用“LALR-by-SLR”方法。 LALR(1)解析器可以通过从语法的LR(0)解析器开始构建,然后为使用与它们对应的LR(0)解析器中的状态的信息注释非终结符的语言创建新的语法。关于该语法中的非终结点的FOLLOW集的信息可以用于计算LR(0)解析器中的前瞻。

最终的结果是

> LR(0)解析器很小,但不是很表达。
> LALR(1)由于前瞻性信息,解析器稍大,但非常有表现力。
> LR(1)解析器是巨大的,但非常有表现力。

至于你的第二个问题 – 你如何确定语法是LR(1)还是LALR(1) – 标准方法是尝试为LR(1)解析器和LALR(1)解析器和检查构建解析自动机为冲突。要构建LR(1)解析器,您将构建LR(1)配置集,然后检查这些配置集中是否有移位/减少冲突或减少/减少冲突。要构建一个LALR(1)解析器,您可以构建LR(1)解析器,然后使用相同的核心集中配置集,或者可以使用基于语言的LR(0)解析器的LALR-by-SLR方法。大多数编译器教科书都提供了有关如何构建这些配置集的详细信息。您还可以查看the lecture notes from a compilers course I taught in Summer 2012,其中涵盖了所有上述解析方法和其他一些方法。

希望这可以帮助!

http://stackoverflow.com/questions/19663564/what-is-the-difference-between-lalr-and-lr-parsing

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:LALR和LR解析有什么区别?