在野牛中有一种方法可以 return 令牌的名称而不是其类型

In bison is there a way to return the Name of a token instead of its type

我正在使用 Flex 和 Bison。在我的 parse.y (bison) 中,我定义了标记。当标记为 return 时,它 return 是一个整数我想知道是否有办法获取该整数并将其映射回野牛源中的实际名称。 例如在我的 parser.y

//define my tokens that are shared with my lexer (flex)
%token <tokenData> ID
%token <tokenData> NUMCONST

在我的语法中我会使用

number : NUMCONST   {std::cout<<"Line "<<->linenum<<" Token: [I want NUMCONST]"<<<std::endl;}

我知道我可以显示从词法分析器 return 编辑的 int,但是 return 令牌的类型,例如 "NUMCONST" 或 "ID"。我想要令牌 "type" 而不是令牌 "int"

bison 生成一个名为 yytokentypeenum,其中包含语法中所有标记的枚举列表。它不提供到包含所有标记名称的字符串的等效映射。

因此,您必须自己实施此映射。也就是说,实现一个实用程序函数,该函数采用 yytokentype 参数和 returns 给定令牌的名称,您随后可以在诊断消息中使用它。另一个无聊的 switch 农场。

话虽如此,编写实用程序 Perl 脚本或等效脚本应该不会太难,它读取来自 bison 的 <filename>.tab.h,解析出 yytokentype 枚举,并自动生成映射函数。使用合适的依赖规则将其粘贴到您的 Makefile 中,您将获得一个令牌到名称映射函数的自动机器人生成器。

可以,但是您需要在 bison 文件中启用该功能。

如果您将指令 %token-table 放入您的 bison 文件中,那么 bison 将生成一个 table 个名为 yytname 的令牌名称。 (您还可以使用 -k--token-table 命令行标志启用此功能。)

yytname[i] 是 "internal bison token code number" 为 i 的代币名称。这与 yylex 返回的数字不同,因为野牛使用名为 yytranslate.

的(未记录的)table 重新编码标记

如果您使用该功能,yytname table 中的令牌名称是令牌 别名 。例如,如果您的语法包括:

%token EQEQ "=="
%%
exp: exp "==" exp
   | exp '+' exp

exp 规则中显示的两个运算符对应的标记名称是 "=="'+'

yytname 还包括非终结符的名称,以备不时之需。

而不是使用 yytranslate[t],您可能想要使用 YYTRANSLATE(t),这是 bison 生成的扫描器本身所做的。该宏将超出范围的整数转换为 2,它具有相应的名称 $undefined。该名称还将显示在 bison 语法中未在任何地方使用的任何单字符标记。

yytnameyytranslate 都在 bison 生成的扫描器中声明为 static const,因此您只能在该文件中存在的代码中使用它们。如果你想公开一个进行翻译的函数,你可以把这个函数放在语法结语中,在第二个 %% 之后。 (例如,如果您想在扫描器中找到与令牌编号对应的名称,您可能需要这样的功能。)它可能看起来像这样:

const char token_name(int t) {
  return yytname[YYTRANSLATE(t)];
}

一般情况下,不需要这样做。如果您只想跟踪解析器在做什么,最好启用 bison 的 trace facility.