编译器,查找FIRST语法集

时间:2017-10-09 11:16:09

标签: parsing compiler-construction context-free-grammar

我正在阅读着名的紫龙书第2版,并且无法从第65页获得关于创建FIRST集的例子:

我们有以下语法(终端加粗):

  

stmt expr;
              | 如果 expr )stmt
              | for (optexpr; optexpr; optexpr)stmt
              | 其他

     

optexpr→ε
              |的 EXPR

本书建议以下是FIRST的正确计算:

  

FIRST(stmt)→{ expr 如果 其他} //就此达成一致

     

FIRST( expr; )→{ expr } //这是从哪里来的?

如评论所示,第二行来自何处​​?

1 个答案:

答案 0 :(得分:5)

教科书中没有错误。

定义了FIRST函数(第64页,添加了重点):

  

α成为语法符号字符串(终结符和/或非终结符号)。我们将FIRST(α)定义为一组终端,它们显示为从α生成的一个或多个终端的第一个符号。

在此示例中, expr ; 是由两个终端组成的一串语法符号,因此它可能是α的值。由于它不包含非终结符,因此它不仅可以自己生成;因此,从α值生成的唯一一串终端正好是 expr ; ,而FIRST(α)中唯一出现的终端是第一个符号string, expr

这可能似乎都是显而易见的,但它引出了你引用的例子中的重要说明:

  

如果有两个作品FIRSTA → α,则必须考虑A → β套。暂时忽略ε-制作,预测解析需要FIRST(α)FIRST(β)不相交

由于 expr; stmt的可能右侧之一,我们需要计算其FIRST集(即使这种情况下的计算是微不足道的)为了测试这个先决条件。