2

我正在尝试使用 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
//...

如果我必须这样做,如果其他模块规范发生变化(这种情况经常发生),维护文件将变得非常困难。

你能告诉我怎么做吗,或者给我指出好的方向(欢迎任何想法/评论)。这对我有很大帮助!提前致谢。

4

2 回答 2

1

而不是这样做:

/* Bison/Yacc file */
%token TokenType1 0x10000000
%token TokenType2 0x11000000
%token TokenType3 0x11100000
//...

您只需要在声明部分包含带有令牌类型的文件

#include "mytoken_enum.h"
// ...
%token TokenType1
%token TokenType2
%token TokenType3 
//...

编辑:这不能做到:

从上面的数字可以看出,Bison 只是按顺序对标记进行编号,并且它在解析器查找表中用作索引,只是为了速度。所以 Bison 不支持这一点,我敢肯定,而且要适应实现模型并不容易。

只需要包装器将真实令牌转换为 yacc/bison 令牌(例如:通过 yylex())

于 2010-01-26T07:36:40.430 回答
0

显而易见的方法是从一种格式转换为另一种格式的小实用程序。如果您确实非常频繁地进行更改,您甚至可以考虑将名称和值存储在 SQL 数据库之类的东西中,并编写几个查询来为每个工具生成正确格式的输出。

select token_name, '=' token_number ','
    from token_table

select '%token ', token_name, ' ', token_number
    from token_table

第一个需要一些按摩,例如在开头添加“enum token_id {”,在结尾添加“};”,但你明白了。当然,还有很多替代品——XML, CSV 等,但总体思路保持不变:存储和编辑尽可能接近原始数据,并自动添加保持工具运行所需的额外“内容”。

于 2010-01-22T05:50:55.603 回答