我正在与 Flex 和 Bison 合作。在我的 parse.y (bison) 中,我定义了 token 。当 token 返回时,它返回一个 int 我想知道是否有办法获取该 int 并将其映射回 Bison 源中的实际名称。
例如在我的 parser.y
//define my tokens that are shared with my lexer (flex)
%token <tokenData> ID
%token <tokenData> NUMCONST
在我的语法中,我然后使用
number : NUMCONST {std::cout<<"Line "<<$1->linenum<<" Token: [I want NUMCONST]"<<<std::endl;}
我知道我可以显示从词法分析器返回的 int 但是否可以返回 token 的类型,例如“NUMCONST”或“ID”。我想要 token “类型”而不是 token “int”
最佳答案
是的,您可以,但您需要在您的 Bison 文件中启用该功能。
如果你把指令 %token-table
进入您的 bison 文件,然后 bison 将生成一个名为 yytname
的 token 名称表。 . (您也可以使用 -k
或 --token-table
命令行标志启用此功能。)yytname[i]
是“内部 Bison token 代码号”为i
的 token 的名称.这与 yylex
返回的数字不同,因为 Bison 使用名为 yytranslate
的(未记录的)表重新编码 token .yytname
中的 token 名称如果您使用该功能,表是 token 别名。例如,如果您的语法包括:
%token EQEQ "=="
%%
exp: exp "==" exp
| exp '+' exp
与两个运算符对应的标记名称显示在
exp
中规则是 "=="
和 '+'
.yytname
还包括非终端的名称,以防您出于任何目的需要这些名称。而不是使用
yytranslate[t]
,你可能想使用 YYTRANSLATE(t)
,这就是 Bison 生成的扫描仪本身所做的。该宏将超出范围的整数转换为 2
, 具有对应的名称 $undefined
.该名称还将显示在 Bison 语法中任何地方都没有使用的任何单字符标记中。两者
yytname
和 yytranslate
已声明 static const
在 Bison 生成的扫描仪中,因此您只能在该文件中存在的代码中使用它们。如果你想公开一个做翻译的函数,你可以把这个函数放在语法结语中,在第二个 %%
之后。 . (例如,如果您想在扫描仪中找到与 token 编号相对应的名称,您可能需要这样的函数。)它可能如下所示:const char token_name(int t) {
return yytname[YYTRANSLATE(t)];
}
通常,没有必要这样做。如果您只想跟踪解析器正在做什么,那么启用 Bison 的 trace facility 会好得多。 .
关于c++ - 在 Bison 中有一种方法可以返回 token 的名称而不是其类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32448461/