如何编写一个bison文件来自动使用C头文件中定义的令牌枚举列表?

时间:2010-01-22 05:30:14

标签: c++ parsing yacc bison lexer

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

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

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

2 个答案:

答案 0 :(得分:1)

而不是:

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

您只需要在声明部分

中包含带有令牌类型的文件
#include "mytoken_enum.h"
// ...
%token TokenType1
%token TokenType2
%token TokenType3 
//...

编辑:无法完成此操作:

  

从上面的数字可以看出,   野牛只是给代币编号   顺序地,它被移位使用   在解析器查找表中作为索引,   速度简单。所以野牛没有   支持,我确信,它   不容易适应   实施模式。

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

答案 1 :(得分:0)

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

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

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

首先需要进行一些按摩,例如将'enum token_id {添加到开头,然后将“};”添加到最后,但是你会得到一般的想法。当然,还有很多选择 - - XML,CSV等,但总体思路保持不变:尽可能靠近原始数据进行存储和编辑,并自动添加保持工具满意所需的额外“东西”。