Parsing 递归下降解析器中文法产生式预测集的计算方法

Parsing 递归下降解析器中文法产生式预测集的计算方法,parsing,compiler-construction,context-free-grammar,Parsing,Compiler Construction,Context Free Grammar,我先理解,然后再理解,但我完全不懂预测集。有人能给我解释一下如何在语法中使用第一个和后面的集合来寻找一个产生式的预测集吗?我没有提供语法,因为这是一个家庭作业,我想知道如何做,而不是如何做这个特定的语法。直观地说,生产的预测集a→ α[注1]是一组终端符号,如果要预测产量,则可能是下一个要读取的符号。(这意味着产品的非终端(A)已经被预测,解析器现在必须决定预测哪个非终端产品。) 显然,这包括可能是右侧的第一个符号的所有终端符号。但是,如果右侧可以导出ε,即空字符串,该怎么办?在这种情况下,输入

我先理解,然后再理解,但我完全不懂预测集。有人能给我解释一下如何在语法中使用第一个和后面的集合来寻找一个产生式的预测集吗?我没有提供语法,因为这是一个家庭作业,我想知道如何做,而不是如何做这个特定的语法。

直观地说,生产的预测集
a→ α
[注1]是一组终端符号,如果要预测产量,则可能是下一个要读取的符号。(这意味着产品的非终端(
A
)已经被预测,解析器现在必须决定预测哪个非终端产品。)

显然,这包括可能是右侧的第一个符号的所有终端符号。但是,如果右侧可以导出ε,即空字符串,该怎么办?在这种情况下,输入中的下一个符号将是在预测的非终端
A
之后的第一个符号;换句话说,它将是
FOLLOW(a)
的成员。因此,预测集包含可能从右侧
α
开始的终端,加上
中的所有符号,如果
α
可以派生空字符串,则跟随(A)
。[注2]

更正式地说,
PREDICT(A→ α) 
是:

  • FIRST(α)
    if
    ε∉ 第一(α)
  • (第一个(α)∪ 遵循(A)-{ε}
    if
    ε∈第一(α)
请记住,我们首先通过“浏览”ε计算句子形式的

第一个(aβ)

  • 第一(a)
    如果
    ε∉ 第一(a)

  • (第一(a){ε})∪ 第一(β)
    if
    ε∈第一(a)

因此,如果右侧的每个符号都可为空,则右侧的第一个
仅包括ε


笔记:
  • 我使用常见的约定,大写字母(
    A
    ..)表示非终结符,小写字母(
    A
    ..)表示语法符号(终结符或非终结符),希腊字母(
    α
    ..)表示可能的空语法符号序列

  • 除了预测开始符号时的第一步之外,当前预测始终包含多个符号。因此,如果
    A
    是下一个要展开的非终结符,并且我们看到它可以为null(即,它不能派生任何内容),我们实际上不需要查找
    FOLLOW(A)
    ,因为我们只需查看predict堆栈,就可以看到我们预测的内容将跟随
    A
    。在某些情况下,这可能允许我们避免与
    a
    的其他备选方案之一发生冲突

    但是,不管怎样,在(A)之后使用
    都是正常的。始终使用
    FOLLOW(A)
    通常被称为“强LL”(SLL)算法。虽然计算已知预测堆栈的第一个集合似乎比使用预计算的跟随集合更强大,但实际上根本没有提高LL解析的能力;每个非LL语法都可以转换为SLL语法