编译器,找到第一个语法集

Compilers, finding FIRST set for grammar

我正在阅读著名的紫龙书第 2 版,无法从第 65 页获取有关创建第一个集合的示例:

我们有以下语法(终端以粗体显示):

stmtexpr;
| if ( expr ) stmt
| for ( optexpr ; optexpr ; optexpr ) stmt
| other

optexpr → ε
| expr

并且书中建议以下是 FIRST 的正确计算:

FIRST(stmt) → {expr, if, for, other} // agree on this

FIRST(expr ;) → {expr} // Where does this come from?

正如评论所说,第二行是从哪里来的?

课本没有错误

定义了 FIRST 函数(在第 64 页,已强调):

Let α be a string of grammar symbols (terminals and/or nonterminals). We define FIRST(α) to be the set of terminals that appear as the first symbols of one or more strings of terminals generated from α.

本例中,expr ;是由两个终结符组成的文法符号串,所以是α的一个可能取值.因为它不包含非终结符,所以它不能只生成自己;因此,从该 α 值生成的唯一终端字符串恰好是 expr ;,并且唯一会出现在 FIRST(α) 中的终端是该字符串中的第一个符号,expr.

这一切似乎都在重复显而易见的事情,但它引出了您引用的示例下方的重要说明:

The FIRST sets must be considered if there are two productions A → α and A → β. Ignoring ε-productions for the moment, predictive parsing requires FIRST(α) and FIRST(β) to be disjoint.

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