如何让Bison解析器关联或读取输入?基于Flex++词法分析器场景
Flex++与Bison解析器的输入实现方案
一、标准联动方案(推荐,无需中间Token文件)
Flex和Bison本身就是设计成配合工作的,不需要额外生成Token文件,直接让Bison调用Flex的词法分析器获取Token即可,步骤如下:
- 调整Flex++词法分析器代码
把原来输出Token到标准输出的逻辑,改成返回Bison定义的Token类型。比如在你的.l文件中,将cout << "IDENTIFIER: " << yytext << endl;这类输出代码,替换为return IDENTIFIER;(IDENTIFIER是你在parse.y中用%token定义的Token名称)。 - 配置Bison解析器
在parse.y的开头代码块中引入Flex++生成的头文件:
运行%{ #include "lex.yy.h" %}bison -d parse.y生成parse.tab.h和parse.tab.c文件(-d选项会生成包含Token定义的头文件)。 - 编写主程序(可选,也可整合到parse.y)
写一个简单的main.cc文件触发解析:#include "parse.tab.h" int main() { yyparse(); // Bison生成的解析入口函数 return 0; } - 编译运行
执行以下命令完成编译:
运行时直接传入输入文件:flex++ your_lexer.l bison -d parse.y g++ main.cc lex.yy.cc parse.tab.c -o parser./parser < input.txt
二、生成Token文件再解析的方案(不推荐)
如果一定要通过中间文件传递Token,可按以下步骤实现:
- 生成Token文件
运行Flex++生成的词法分析器,将Token输出到文件:
注意要统一Token的输出格式,比如每行一个Token,格式为./your_lexer < input.txt > tokens.txtTOKEN_TYPE 对应值(例如IDENTIFIER var1)。 - 修改Bison解析器的词法输入逻辑
在parse.y的代码块中实现自定义的词法读取函数,替代默认的yylex():%{ #include <fstream> #include <string> using namespace std; ifstream token_file("tokens.txt"); string token_type; string token_value; int yylex() { if (token_file >> token_type >> token_value) { // 根据token_type返回对应的Bison Token值 if (token_type == "IDENTIFIER") return IDENTIFIER; else if (token_type == "NUMBER") return NUMBER; // 其他Token类型依次处理 } return 0; // 结束标记 } %} - 编译运行
编译命令类似标准方案,但无需链接Flex++生成的代码:bison -d parse.y g++ parse.tab.c -o parser ./parser
注意:这种方案需要手动处理Token的同步、错误恢复等问题,代码复杂度更高,且性能不如标准联动方案,仅在特殊场景下使用。
内容的提问来源于stack exchange,提问作者chickennuggies
相关产品推荐
相关产品推荐

