递归文法可以有 LR(0) 状态吗? 注释

问题描述

在这个例子中:

S -> aA
A -> Aa|b

上述语法生成的语言(字符串集)是无限的。是否有可能找到它的 LR(0) 状态机?

解决方法

语法没有“a”LR(0) 状态。您可以为语法构造一个 LR(0) 状态机;那台机器有几个状态。

这是您的语法的 LR(0) 状态机,由 Grammophone 生成:

LR(0) state machine for given grammar

上面的状态机没有显示reduce transitions,但是可以从每个状态的item中推导出来;末尾带有 • 项的状态是归约状态(状态 1、3、4 和 5)。由于 LR(0) 解析器可能不会参考下一个标记来决定是否进行归约,因此语法不是 LR(0);状态 3 既有转移又有归约 [注 1]。

虽然语法不是 LR(0),但 LR(0) 状态机仍然很重要,因为 SLR(1) 和 LALR(1) 解析器使用相同的状态机,它们具有完全相同的状态。因此,构建 SLR(1) 和 LALR(1) 解析器从构建 LR(0) 状态机开始。不同之处在于 SLR(1) 和 LALR(1) 解析器确实使用 (1) 前瞻符号来确定缩减操作。使用这两种算法中的任何一种,状态 3 中的冲突都将得到解决,因为减少仅与 b 的前瞻相关联,在状态机中没有转换。

规范的 LR(1) 解析器不使用相同的状态机(在大多数情况下);在 CLR 解析器中,可能有两个状态具有相同的项目集。这有时可以解决冲突。但是在这个语法中它是没有必要的。

注释

  1. 如果语言具有前缀属性,它只能是 LR(0);换句话说,没有一个句子是另一个句子的前缀。 (将其称为“无前缀属性”可能会更好,但这并不容易谈论。)为语言提供前缀属性的最简单方法是为每个输入添加一个输入结束标记(通常用符号 $)。输入结束标记必须是一个新符号,它不会出现在语法中的任何地方。由于新语言中的每个句子都以 $ 结尾,并且除了结尾之外没有任何句子包含 $,因此一个句子不可能成为另一个句子的前缀。

    所以要使这个语法为 LR(0),只需将规则 S -> a A 更改为 S -> a A $。这解决了状态 3 中的 shift-reduce 冲突,并且仍然产生无限语言。

,

不是LR(0)。留声机告诉我:

LR(0) 不是 LR(0) — 它包含一个 shift-reduce 冲突。

添加 E -> S end-of-input . 也无济于事,您需要使用 LR(1)。

enter image description here