0

我正在尝试在 C++ Bison 中获取令牌的名称:例如%token <int> TPLUS "+" TMINUS "-" TMUL "*" TDIV "/"

然而,在 Bison 的 C++ 变体中,%token-table不做任何事情。

我注意到生成的野牛代码中有一个令牌映射: const char* const parser::yytname_[];但是它是私有的。

有谁知道如何在 C++ Bison 中获取这些标记的名称?这甚至可以使用 C++ 变体吗?

我知道这里有人问过这个问题,但没有公认的答案。

使用版本 3.4.3

4

2 回答 2

1

首先,确保您拥有最新版本的 Bison(我相信最低版本是 v3.6,但 v3.7 版本有几个有用的错误修复)。

这将生成一个symbol_name使用以下原型之一命名的静态成员函数。请注意,`token_symbol_kind 是 内部令牌编号,而不是扫描仪生成的值。(见下文)

const char* yy::parser::symbol_name(token_symbol_kind)  (1)
std::string yy::parser::symbol_name(token_symbol_kind)  (2)

(1) if %define parse.error custom|detailed
(2) if %define parse.error verbose

parse.error如果未定义该选项,那么您仍然可以symbol_name使用 deprecated%token-table指令获取定义,或者如果您安排#define YYDEBUG插入到生成的代码中(-d例如,请参见标志)。我不知道为什么返回类型会根据parse.error.

如前所述,参数 tosymbol_name是 bison 内部令牌编号,而不是扫描仪返回的令牌类型。parser您可以使用成员类获取令牌类型的内部令牌编号,by_kind表达式如下yy::parser::by_kind(yy::parser::token::«token-type-name»).type_get()

于 2021-06-18T01:00:22.763 回答
0

确保你的野牛是我的最新版本(3.7.3)。令牌的名称可以通过以下方式派生:

std::cout << yy::parser::symbol_name(yy::parser::by_kind(yy::parser::token::TPLUS).type_get()) << std::endl;

y::parser::token::TPLUS你的令牌在哪里。

于 2021-06-18T00:39:38.193 回答