我正在阅读着名的紫龙书第2版,并且无法从第65页获得关于创建FIRST集的例子:
我们有以下语法(终端加粗):
stmt → expr;
| 如果( expr )stmt
| for (optexpr; optexpr; optexpr)stmt
| 其他optexpr→ε
|的 EXPR
本书建议以下是FIRST的正确计算:
FIRST(stmt)→{ expr ,如果, ,其他} //就此达成一致
FIRST( expr; )→{ expr } //这是从哪里来的?
如评论所示,第二行来自何处?
答案 0 :(得分:5)
教科书中没有错误。
定义了FIRST
函数(第64页,添加了重点):
让
α
成为语法符号字符串(终结符和/或非终结符号)。我们将FIRST(α)
定义为一组终端,它们显示为从α生成的一个或多个终端的第一个符号。
在此示例中, expr ; 是由两个终端组成的一串语法符号,因此它可能是α的值。由于它不包含非终结符,因此它不仅可以自己生成;因此,从α值生成的唯一一串终端正好是 expr ; ,而FIRST(α)
中唯一出现的终端是第一个符号string, expr 。
这可能似乎都是显而易见的,但它引出了你引用的例子中的重要说明:
如果有两个作品
FIRST
和A → α
,则必须考虑A → β
套。暂时忽略ε-制作,预测解析需要FIRST(α)
和FIRST(β)
不相交。
由于 expr; 是stmt
的可能右侧之一,我们需要计算其FIRST
集(即使这种情况下的计算是微不足道的)为了测试这个先决条件。