我正在尝试使用 Bison/Yacc 构建一个解析器,以便能够解析另一个模块完成的令牌流。令牌已在枚举类型中列出,如下所示:
// C++ header file
enum token_id {
TokenType1 = 0x10000000,
TokenType2 = 0x11000000,
TokenType3 = 0x11100000,
//... and the list go on with about 200/300 line
};
我已经多次浏览了 bison 的文档,但我找不到比像这样复制 Bison 文件中的每个令牌更好的解决方案:
/* Bison/Yacc file */
%token TokenType1 0x10000000
%token TokenType2 0x11000000
%token TokenType3 0x11100000
//...
如果我必须这样做,如果其他模块规范发生变化(这种情况经常发生),维护文件将变得非常困难。
您能否告诉我该怎么做,或者为我指出好的方向(欢迎任何想法/评论)。这对我会有很大帮助!提前致谢。
而不是做:
/* Bison/Yacc file */
%token TokenType1 0x10000000
%token TokenType2 0x11000000
%token TokenType3 0x11100000
//...
您只需要在声明部分包含具有令牌类型的文件
#include "mytoken_enum.h"
// ...
%token TokenType1
%token TokenType2
%token TokenType3
//...
编辑:这是无法完成的:
从上面的数字可以看出, Bison 只是对标记进行编号 顺序地,并且使用移位 在解析器查找表中作为索引, 只是为了速度。所以野牛不 我确信支持这一点 不容易适应 实施模型。
只需要一个包装器将真实令牌转换为 yacc/bison 令牌(例如:通过 yylex())
显而易见的方法是使用一个小实用程序将一种格式转换为另一种格式。如果您确实经常进行更改,您甚至可以考虑将名称和值存储在 SQL 数据库之类的内容中,并编写几个查询来为每个工具生成正确格式的输出。
select token_name, '=' token_number ','
from token_table
select '%token ', token_name, ' ', token_number
from token_table
第一个需要一些修改,例如在开头添加“enum token_id {”,在末尾添加“};”,但您已经了解了总体思路。当然,还有很多替代方案 - XML 、CSV 等,但总体思路保持不变:存储和编辑尽可能接近原始数据,并自动添加保持工具满意所需的额外“内容”。