【问题标题】:What do the different kinds of LR Parsers use as lookahead?不同种类的 LR 解析器使用什么作为前瞻?
【发布时间】:2018-03-30 01:00:01
【问题描述】:
  1. 如果下一个输入符号没有转换(因为它没有前瞻),那么 LR(0)-Parsers 简单地减少是否正确?
  2. SLR(1)-Parsers 使用产生式的 FOLLOW-Set 作为前瞻是否正确?
  3. LR(1)-Parsers 使用 FIRST-,而不是 FOLLOW-Set 作为前瞻是否正确?

closure 的算法显然使用了FIRST

closure(S)
For each item [A → α ⋅ B β, t] in S,
  For each production B → γ in G,
    For each token b in FIRST(βt),
      Add [B → ⋅ γ, b] to S

再一次,我对此感到困惑。

4.7.1 Canonical LR(1) Items段下龙书说:

因此,我们只能在那些输入符号上减少 A → α a 其中 [A → α·, a] 是一个 LR(1) 项 堆。此类 a 的集合将始终是 FOLLOW(A) 的子集, 但它可能是一个适当的子集,如示例 4.51 所示。

【问题讨论】:

    标签: parsing lr bottom-up


    【解决方案1】:
    1. LR(0) 解析器没有前瞻功能,因此如果在给定的解析器状态下两者都可能,则它无法决定减少和移位操作。所以 reduce 状态不能有 shift 转换。

    2. 是的,SLR 算法仅使用被归约的非终结符的 FOLLOW 集,高估了每个归约操作的前瞻集。

    3. 没有。规范的 LR 算法根据解析器上下文(即状态)为每个动作计算一个前瞻集。为了计算这个集合,知道每个非终结符的 FIRST 集是有用的(并且能够计算任何句子形式的 FIRST 集),但是计算的前瞻集不是任何非终结符的 FIRST 集。正如教科书中所指出的,它是被约简的非终结符的 FOLLOW 集合的子集,并且在某些语法的某些状态下,它将是一个适当的子集。这意味着两个不同状态的“相同”减少可能具有不同的前瞻集,因为这两个状态是在不同的上下文中达到的。正如您所指出的,教科书提供了一个示例,值得详细研究这个示例。

    【讨论】:

    • 那么在 LR(1) 中使用的第一个集合是在点右侧的非终结符加上前瞻之后的其余项目(如上面的示例算法所述)?如果是,我可以看到这将是点右侧非终结符的 FOLLOW 集的子集。
    • @vonspotz:我想你已经正确理解了闭包函数中的算法。
    猜你喜欢
    • 1970-01-01
    • 2013-04-13
    • 1970-01-01
    • 2010-09-19
    • 2019-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多