【问题标题】:What is the precise definition of a lookahead set?前瞻集的精确定义是什么?
【发布时间】:2010-09-15 19:04:54
【问题描述】:

我正在玩弄编写编译器并学习语法分析背后的理论。我发现尽管它是理解识别算法的关键概念,但网络上关于它的信息却相当贫乏。看来 StackOverflow 可以解决这个问题。

【问题讨论】:

  • 简单的答案是,“在某些情况下您期望接下来的一组标记”。

标签: compiler-construction compiler-theory


【解决方案1】:

语法的前瞻集是根据其每个非终结符的前瞻集定义的,而前瞻集又依赖于每个产生式的前瞻集。确定前瞻集可以帮助我们确定语法是否为LL(1),如果是,我们需要哪些信息来为其构造递归下降解析器。

定义: LOOKAHEAD(X -> α)LOOKAHEAD(X)

LOOKAHEAD(X -> α) = FIRST(α) U FOLLOW(X), if NULLABLE(α)
LOOKAHEAD(X -> α) = FIRST(α), if not NULLABLE(α)
LOOKAHEAD(X) = LOOKAHEAD(X -> α) U LOOKAHEAD(X -> β) U LOOKAHEAD(X -> γ)

其中 FIRST(α) 是 α 可以开头的终结符集合,FOLLOW(X) 是可以出现在 之后的终结符集合X 在语法中的任何位置,NULLABLE(α) 是 α 是否可以推导出一个空的终结符序列(记为 ε)。以下定义取自 Torben Mogensen 的免费书籍Basics of Compiler Design请参见下面的示例。

定义: NULLABLE(X)

NULLABLE(ε) = true
NULLABLE(x) = false, if x is a terminal
NULLABLE(αβ) = NULLABLE(α) and NULLABLE(β)
NULLABLE(P) = NULLABLE(α_1) or NULLABLE(α_2) or ... or NULLABLE(α_n),
               if P is a non-terminal and the right-hand-sides
               of all its productions are α_1, α_2, ..., α_n.

定义: FIRST(X)

FIRST(ε) = Ø
FIRST(x) = {x}, assuming x is a terminal
FIRST(αβ) = FIRST(α) U FIRST(β), if NULLABLE(α)
          = FIRST(α), if not NULLABLE(α)
FIRST(P) = FIRST(α_1) U FIRST(α_2) U ... U FIRST(α_n),
               if P is a non-terminal and the right-hand-sides
               of all its productions are α_1, α_2, ..., α_n.

定义: FOLLOW(X)

结束符 a 在 FOLLOW(X) 中当且仅当从文法的起始符 S 有一个推导使得 S ⇒ αX aβ,其中 α 和 β 是(可能空) 语法符号序列。

直觉: FOLLOW(X)

看看X在语法中出现的位置。所有可以跟随它(直接或通过任何级别的递归)的终端都在FOLLOW(X)中。此外,如果 X 出现在产生式的末尾(例如 A -> foo X),或者后面跟着可以减少为 ε 的其他内容(例如 A -> foo X BB -> ε),那么无论 A 后面可以跟,X 后面也可以跟(即FOLLOW(A) ⊆ FOLLOW(X))。

请参阅 Torben 的书中确定 FOLLOW(X) 的方法以及下面的演示。

一个例子:

E -> n A
A -> E B
A -> ε
B -> + A
B -> * A

首先,NULLABLEFIRST是确定的:

NULLABLE(E) = NULLABLE(n A) = NULLABLE(n) ∧ NULLABLE(A) = false
NULLABLE(A) = NULLABLE(E B) ∨ NULLABLE(ε) = true
NULLABLE(B) = NULLABLE(+ A) ∨ NULLABLE(* A) = false

FIRST(E) = FIRST(n A) = {n}
FIRST(A) = FIRST(E B) U FIRST(ε) = FIRST(E) U Ø = {n} (because E is not NULLABLE)
FIRST(B) = FIRST(+ A) U FIRST(* A) = FIRST(+) U FIRST(*) = {+, *}

在确定FOLLOW 之前,会添加产生式E' -> E $,其中$ 被视为“文件结尾”非终端。然后确定FOLLOW

FOLLOW(E): Let β = $, so add the constraint that FIRST($) = {$} ⊆ FOLLOW(E)
           Let β = B, so add the constraint that FIRST(B) = {+, *} ⊆ FOLLOW(E)
FOLLOW(A): Let β = ε, so add the constraint that FIRST(ε) = Ø ⊆ FOLLOW(A).
           Because NULLABLE(ε), add the constraint that FOLLOW(E) ⊆ FOLLOW(A).
           Let β = ε, so add the constraint that FIRST(ε) = Ø ⊆ FOLLOW(A).
           Because NULLABLE(ε), add the constraint that FOLLOW(B) ⊆ FOLLOW(A).
           Let β = ε, so add the constraint that FIRST(ε) = Ø ⊆ FOLLOW(A).
           Because NULLABLE(ε), add the constraint that FOLLOW(B) ⊆ FOLLOW(A).
FOLLOW(B): Let β = ε, so add the constraint that FIRST(ε) = Ø ⊆ FOLLOW(B).
           Because NULLABLE(ε), add the constraint that FOLLOW(A) ⊆ FOLLOW(B).

解决这些约束(也可以通过定点迭代来实现),

    {+, *, $} ⊆ FOLLOW(E)
    FOLLOW(E) ⊆ FOLLOW(A)
    FOLLOW(A) = FOLLOW(B)

    FOLLOW(E) = FOLLOW(A) = FOLLOW(B) = {+, *, $}.

现在可以确定每个生产的LOOKAHEAD

LOOKAHEAD(E -> n A) = FIRST(n A) = {n}     because ¬NULLABLE(n A)
LOOKAHEAD(A -> E B) = FIRST(E B)           because ¬NULLABLE(E B)
                    = FIRST(E) = {n}       because ¬NULLABLE(E)
LOOKAHEAD(A -> ε)   = FIRST(ε) U FOLLOW(A) because NULLABLE(ε)
                    = Ø U {+, *, $} = {+, *, $}
LOOKAHEAD(B -> + A) = FIRST(+ A)           because ¬NULLABLE(+ A)
                    = FIRST(+) = {+}       because ¬NULLABLE(+)
LOOKAHEAD(B -> * A) = {*}                  for the same reason

最后,LOOKAHEAD可以确定每个非终结符:

LOOKAHEAD(E) = LOOKAHEAD(E -> n A) = {n}
LOOKAHEAD(A) = LOOKAHEAD(A -> E B) U LOOKAHEAD(A -> ε)   = {n} U {+, *, $}
LOOKAHEAD(B) = LOOKAHEAD(B -> + A) U LOOKAHEAD(B -> * A) = {+, *}

通过这些知识,我们可以确定这个语法不是 LL(1),因为它的非终结符有重叠的前瞻集。 (也就是说,我们不能创建一个程序来一次读取一个符号并明确决定使用哪个产生式。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-03
    • 2020-02-05
    • 2014-08-04
    • 1970-01-01
    • 2023-01-31
    相关资源
    最近更新 更多