【问题标题】:Can a recursive grammar have a LR(0) state?递归文法可以有 LR(0) 状态吗?
【发布时间】:2021-09-16 16:29:27
【问题描述】:

在这个例子中:

S -> aA
A -> Aa|b

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

【问题讨论】:

    标签: context-free-grammar shift-reduce-conflict


    【解决方案1】:

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

    这是一个用于语法的 LR(0) 状态机,由 Grammophone 生成:

    上面的状态机没有显示归约转移,但是可以从每个状态的项中推导出来;以 • 结尾的项目的状态是归约状态(状态 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 冲突,并且仍然产生无限语言。

    【讨论】:

    • Yes S -> a $ 似乎有效。但是状态现在是 7 (0,1,2,3,4,5,6),而不是图中的 6 (0,1,2,3,4,5)。
    • @MostowskiCollapse:这当然是真的,但我看不出它与这个问题有什么关系。问题是,“无限语言可以有 LR(0) 状态吗?”我将其解释为“无限语言可以有一个 LR(0) 状态机吗?”,答案是“是的,你可以为任何上下文无关语法创建一个 LR(0) 状态机”。您似乎将其解释为“无限语言可以有 LR(0) 解析器吗?”,答案也是“是的;这种特定语言没有,因为它没有前缀属性,但很容易找到一种无限的语言。”
    • 也许该评论应该是答案。但我认为添加更多细节并没有什么坏处。
    • 我已经编辑了问题(用状态机替换了状态),因此不需要更多的猜测工作。如果 G 正是问题中显示的语法,则答案可能是否定的。但是使用具有与 G 相似意图的不同语法 G'(你的 S -> a $)似乎可行。
    【解决方案2】:

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

    LR(0) 不是 LR(0) — 它包含移位归约冲突。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-14
      • 2013-10-09
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 2011-12-28
      • 2012-04-01
      • 2021-08-19
      相关资源
      最近更新 更多