我正在与Flex和Bison合作。在我的parse.y(野牛)我定义了令牌。当令牌返回时,它返回一个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但是在那里返回令牌的类型,例如&#34; NUMCONST&#34;或&#34; ID&#34;。我想要令牌&#34;输入&#34;而不是令牌&#34; int&#34;
答案 0 :(得分:11)
是的,你可以,但你需要在你的野牛文件中启用该功能。
如果您将指令%token-table
放入您的bison文件中,那么bison将生成一个名为yytname
的令牌名称表。 (您还可以使用-k
或--token-table
命令行标志启用此功能。)
yytname[i]
是“内部野牛令牌代码编号”为i
的令牌的名称。这与yylex
返回的数字不同,因为bison使用名为yytranslate
的(未记录的)表格对令牌进行重新编码。
如果您使用该功能,yytname
表中的令牌名称是令牌别名。例如,如果您的语法包括:
%token EQEQ "=="
%%
exp: exp "==" exp
| exp '+' exp
exp
规则中显示的与两个运算符对应的标记的名称为"=="
和'+'
。
yytname
还包括非终端的名称,以防您出于任何目的需要。
您可能希望使用yytranslate[t]
,而不是使用YYTRANSLATE(t)
,这是Bison生成的扫描程序本身所做的事情。该宏将超出范围的整数转换为2
,其具有相应的名称$undefined
。该名称还将显示在野牛语法中未使用的任何单字符标记。
bison生成的扫描程序中yytname
和yytranslate
都声明为static const
,因此您只能在该文件中存在的代码中使用它们。如果要公开一个执行翻译的函数,可以在第二个%%
之后将函数放在语法结尾中。 (例如,如果您想在扫描仪中找到与令牌编号对应的名称,则可能需要这样的功能。)它可能如下所示:
const char token_name(int t) {
return yytname[YYTRANSLATE(t)];
}
通常,没有必要这样做。如果您只是想跟踪解析器正在做什么,那么最好启用bison的trace facility。
答案 1 :(得分:1)
bison
生成一个名为enum
的{{1}},其中包含语法中所有令牌的枚举列表。它不提供与包含所有令牌名称的字符串的等效映射。
因此,您必须自己实施此映射。也就是说,实现一个带有yytokentype
参数的实用程序函数,并返回给定标记的名称,您可以随后在诊断消息中使用该名称。另一个无聊的yytokentype
农场。
话虽如此,编写一个实用程序switch
脚本或同等程序,读取来自野牛的Perl
并解析{{1}枚举和robo生成映射函数。使用合适的依赖关系规则将其粘贴到您的<filename>.tab.h
中,然后您自己获得了一个令牌到名称映射函数的自动生成器。