c++ - 在 Bison 中有一种方法可以返回 token 的名称而不是其类型

标签 c++ c parsing bison flex-lexer

我正在与 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 语法中任何地方都没有使用的任何单字符标记中。

两者 yytnameyytranslate已声明 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/

相关文章:

c++ - 包含自定义头文件的编译器错误

c++ - SDL 2.0 按键重复和延迟

c - 在资源有限的平台上使用 memset 设置内存?

java - 解析泛型类型描述

c# - 正则表达式挑战 : changing formats of negative numbers

c++ - 没有键盘输入的 SFML 动画

c++ - ZMQ : Sending custom CPP object over the ZMQ queue

c - 解释数据表中的十六进制并使用 C 按位​​左移运算符进行转换

c++ - 什么时候 sizeof(myPOD) 太大而无法在 x64 上按值传递?

Java:使用 SAXParser 拆分大型 XML 文件