Bison 中特殊 $end 令牌的友好名称

Friendly name for special $end token in Bison

对于旧版本的 Bison,冗长的错误消息有时如下所示:

syntax error, unexpected [, expecting $end

有没有办法给$end一个更方便用户的名字?在较新的版本中,这是“文件结尾”。我也可以在旧版本中获得它吗?

对于用户定义的标记,我可以将名称指定为 %token NUM "number",但是如何为 $end 指定名称?

如果要为 end-of-input 令牌指定别名,可以使用:

%token END 0 "friendly name"

声明令牌 ID END 的代码为 0,并为该代码提供一个友好的名称。

您可以使用任何其他未使用的符号来代替 END,例如 ZEROFRED。无论您使用什么符号,都将 #defined 变为 0,或者声明为值为 0 的 enum 标签(取决于 bison 版本),但只要您不使用该符号,事实就是不是很有趣。

您不能使用 YYEOFEOF,因为它们都是保留的(并且有其他定义)。第一个由 Bison 本身保留,所有以 yyYY 开头的符号也是如此,第二个由 C 保留。如果您尝试重新定义保留名称(无论是手动还是使用代码生成器)结果是未定义的行为,无论您是否看到诊断以及它是否在某些情况下似乎有效。

%token 声明的语法是一系列三元组,由一个符号、一个可选的文字整数和一个可选的带引号的字符串组成。您想将别名(带引号的字符串)与令牌代码(整数)相关联,但语法不允许您在不指定某些符号的情况下执行此操作。明确的令牌代码很少有用,因此限制不是特别繁重。 end-of-input 代码 0 可能是唯一有用的显式代码。

请注意,%token END YYEOF "foo"(取自其中一条评论)声明了 两个 令牌,它们都具有由 Bison 选择的代码。 (其中一个符号名称是保留的,这会导致未定义的行为,如上所述。)所以这肯定不是您想要的。如果您要为代码 0 提供别名,则必须有一个包含文字整数 0 的标记声明。

据记载,在描述与词法分析器交互的部分中,0 是输入结束的标记代码。 0 是词法分析器指示输入结束的方式。这是 C 接口的一个固定方面,并且可以安全地假设它将在无限期的未来继续工作。 yylex 也可以 return 一个具有相同效果的负数,但它被转换为标记代码 0。使用 %token END 0 "..." 声明输入结束的别名出现在示例代码中手册,以及任意数量的 real-life 解析器(和 SO 答案)。