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

ajp*_*nam 3 c c++ parsing bison flex-lexer

我正在与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
Run Code Online (Sandbox Code Playgroud)

在我的语法中我然后使用

number : NUMCONST   {std::cout<<"Line "<<$1->linenum<<" Token: [I want NUMCONST]"<<<std::endl;}
Run Code Online (Sandbox Code Playgroud)

我知道我可以显示从词法分析器返回的int但是在那里返回令牌的类型,例如"NUMCONST"或"ID".我想要令牌"类型"而不是令牌"int"

ric*_*ici 13

是的,你可以,但你需要在你的野牛文件中启用该功能.

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

yytname[i]是"内部野牛令牌代码编号"所在的令牌的名称i.这与返回的数字不同yylex,因为bison使用一个(未记录的)表来重新编码令牌yytranslate.

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

%token EQEQ "=="
%%
exp: exp "==" exp
   | exp '+' exp
Run Code Online (Sandbox Code Playgroud)

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

yytname 还包括非终端的名称,以防您出于任何目的需要.

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

双方yytnameyytranslate声明static const在野牛生成的扫描仪,所以你只能在代码中存在于文件中使用它们.如果要公开一个执行翻译的函数,可以在第二个函数后将函数放入语法结尾%%.(例如,如果您想在扫描仪中找到与令牌编号对应的名称,则可能需要这样的功能.)它可能如下所示:

const char token_name(int t) {
  return yytname[YYTRANSLATE(t)];
}
Run Code Online (Sandbox Code Playgroud)

通常,没有必要这样做.如果您只想跟踪解析器正在执行的操作,那么启用bison的跟踪功能会更好.

  • 这是正确的答案,而不是被接受的答案.无需解析bison输出文件. (3认同)