使用Flex与Bison开发编译器时GCC报错yyin等标识符未声明
核心报错原因
你开启了Flex的reentrant(可重入)模式,该模式下传统的全局变量yyin、yyout、yyleng、yytext都会被取消,所有扫描器状态都封装在yyscan_t类型的实例中,你的编译报错是以下几个配置错误共同导致的:
具体修改方案
1. 修复funlang.l的语法错误
你在识别int关键字的规则里漏写了分号:- "int" {return INT_KEYWORD } + "int" {return INT_KEYWORD; }2. 调整头文件包含顺序
可重入模式下,需要先引入Lexer.h再引入Parser.h,修改两处:- funlang.l的
%{ %}块:%{ #include <stdint.h> #include <string.h> - #include "Parser.h" - #include "Lexer.h" + #include "Lexer.h" + #include "Parser.h" size_t line_count = 1; %} - eval.h的包含顺序:
- #include "Parser.h" - #include "Lexer.h" + #include "Lexer.h" + #include "Parser.h"
- funlang.l的
3. 修复Makefile的链接顺序和依赖
链接时-lfl库必须放在编译目标的后面,同时补充正确的依赖关系:CC = gcc CFLAGS = -O2 -Wall -Wextra -Wpedantic LDFLAGS = -lfl INFILES = main.c Parser.c Lexer.c OUTFILE = language default: $(OUTFILE) $(OUTFILE): Lexer.c Parser.c main.c $(CC) $(CFLAGS) $(INFILES) -o $(OUTFILE) $(LDFLAGS) Lexer.c: funlang.l flex funlang.l Parser.c: funlang.y bison -d -Wcounterexamples funlang.y clean: rm -f Lexer.* Parser.* $(OUTFILE)4. 修复可重入模式下的变量引用(解决后续运行问题)
可重入模式下yylineno是扫描器的内置成员,不需要自己定义全局的line_count统计行号,直接使用即可:%{ #include <stdint.h> #include <string.h> #include "Lexer.h" #include "Parser.h" - size_t line_count = 1; %} %% \n {yylineno++; } . {printf("Error, unrecognized char at line #%i", yylineno); return OTHER; }
完成以上修改后即可解决当前的yyin未声明类的编译错误,后续你需要初始化yyscan_t扫描器实例、关联输入文件后再调用yyparse即可完成解析流程。
内容的提问来源于stack exchange,提问作者Arturo Contreras
相关产品推荐
相关产品推荐

