【问题标题】:How to calculate FIRST sets by hand如何手动计算 FIRST 组
【发布时间】:2013-10-28 11:44:09
【问题描述】:

我的导师提供的例子之一我听不懂。

例子

S ::= aBA | BB | Bc
A ::= Ad | d
B ::= ε

我们有

FIRST(B) = FIRST(ε)
         = {ε}

FIRST(A) = FIRST(Ad) ∪ FIRST(d)
         = FIRST(A) ∪ {d}
         = {d}

FIRST(S) = FIRST(aBA) ∪ FIRST(BB) ∪ FIRST(Bc)
         = FIRST(a) ∪ (FIRST(B)\{ε}) ∪ FIRST(B) ∪ (FIRST(B)\{ε) ∪ FIRST(c)
         = {a, ε, c}

为什么在 FIRST(S) 计算中有 FIRST(B)?不应该吗

(FIRST(B)\{ε)?

为什么 FIRST(S) 计算中缺少 A?

【问题讨论】:

    标签: parsing compiler-construction grammar


    【解决方案1】:

    This page 给出了派生 FIRST(和 FOLLOW)集合的机械规则。我将尝试解释这些规则背后的逻辑以及它们如何应用于您的示例。

    第一组

    FIRST(u) 是可以在u 的完整派生中首先出现的终结符集合,其中u 是终结符和非终结符的序列。换句话说,在计算FIRST(u) 集合时,我们只寻找可能是从u 派生的字符串的第一个终端的终端。

    FIRST(aBA)

    根据定义,我们可以看到FIRST(aBA) 减少为FIRST(a),然后减少为a。这是因为无论AB 产生是什么,终端a 总是首先出现在从aBA 派生的任何东西中,因为a 是一个终端,并且不能从前面移除的顺序。

    FIRST(Bc)

    我现在要跳过FIRST(BB),然后转到FIRST(Bc)。这里的情况有所不同,因为B 是非终端。起初,我们说FIRST(B) 中的任何东西也在FIRST(S) 中。不幸的是,FIRST(B) 包含 ε 这会导致问题,因为我们可能会遇到这种情况

       FIRST(Bc)
    -> FIRST(εc)
    =  FIRST(c)
    =  c
    

    其中箭头是可能的推导/归约。一般来说,我们因此说FIRST(Xu),其中εFIRST(X) 中,等于(FIRST(X)\{ε}) ∪ FIRST(u)。这解释了您计算中的最后两项。

    FIRST(BB)

    使用上述规则,我们现在可以将FIRST(BB) 推导出为(FIRST(B)\{ε}) ∪ FIRST(B)。同样,如果我们计算FIRST(BBB),我们会将其减少为

      FIRST(BBB)
    = (FIRST(B)\{ε}) ∪ FIRST(BB)
    = (FIRST(B)\{ε}) ∪ (FIRST(B)\{ε}) ∪ FIRST(B)
    

    值得注意的是,在计算 FIRST 集合时,符号序列中的最后一个符号永远不会从中删除空字符串,因为此时,空字符串是合理的可能性。这可以从您的示例中的可能推导中看出:

       S
    -> BB
    -> εε
    -> ε
    

    希望您可以从以上所有内容中了解为什么 FIRST(B) 出现在您的计算中,而 FIRST(A) 没有出现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-15
      • 2014-07-17
      • 2017-07-17
      • 2018-12-21
      • 1970-01-01
      • 1970-01-01
      • 2015-01-28
      • 2012-09-14
      相关资源
      最近更新 更多