Flex&Bison计算器编译报错:未定义引用及libfl库缺失求助
解决Flex+Bison简易计算器的编译错误
问题描述
使用Flex和Bison编写简易计算器时,先后遇到cannot find -lfl、未定义引用yylval/yyerror,以及WinMain@16未定义等编译错误。相关代码如下:
Flex代码(calculator.l)
%option noyywrap %{ #include "calculator.tab.h" int yyerror(const char *); %} %% [ \t] [0-9]+ { yylval = atoi(yytext); return NUMBER; } "+" { return ADD; } "*" { return MUL; } "^" { return EXPONENT; } "(" { return LPAREN; } ")" { return RPAREN; } \n { return 0; } . { yyerror("Invalid character"); } %%
Bison代码(calculator.y)
%{ #include <stdio.h> #include <stdlib.h> %} %token NUMBER ADD MUL EXPONENT LPAREN RPAREN %left ADD %left MUL %left EXPONENT %% input: | input line ; line: expr { printf("Result: %d\n", $1); } ; expr: NUMBER | expr ADD expr { $$ = $1 + $3; } | expr MUL expr { $$ = $1 * $3; } | expr EXPONENT expr { $$ = power($1, $3); } | LPAREN expr RPAREN { $$ = $2; } ; %% int power(int base, int exp) { int result = 1; for (; exp > 0; --exp) { result *= base; } return result; } int yyerror(const char *s) { fprintf(stderr, "Error: %s\n", s); return 0; } int main() { yyparse(); return 0; }
遇到的错误信息
C:\Users\paart\AppData\Local\Temp\cci2ZuAz.o:lex.yy.c:(.text+0x1b1): undefined reference to `yylval' C:\Users\paart\AppData\Local\Temp\cci2ZuAz.o:lex.yy.c:(.text+0x203): undefined reference to `yyerror' c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../libmingw32.a(main.o):(.text.startup+0xa0): undefined reference to `WinMain@16' collect2.exe: error: ld returned 1 exit status
错误分析与解决步骤
1. 未定义yylval/yyerror的问题
- 原因:
yylval是Bison自动生成的全局变量,yyerror在Bison代码中实现,单独编译Flex生成的lex.yy.c时,未包含Bison生成的calculator.tab.c,导致链接时找不到这些符号。 - 解决:编译时必须同时包含Flex和Bison生成的C文件。
2. WinMain@16未定义的问题
- 原因:MinGW默认尝试编译Windows GUI程序,而计算器是控制台程序,导致入口函数不匹配。
- 解决:编译时添加
-mconsole参数,强制编译为控制台程序。
3. 找不到-lfl库的问题
- 原因:添加
%option noyywrap后,Flex不再依赖libfl.a中的yywrap函数,无需链接该库;之前的库路径写法错误(-l后应跟库名,路径需用-L指定)。 - 解决:无需添加
-lfl参数,若确实需要链接,正确写法为-LC:\GnuWin32\lib -lfl。
完整正确编译流程
执行以下命令完成编译:
# 1. 用Bison生成语法分析器头文件和源文件 bison -d calculator.y # 2. 用Flex生成词法分析器源文件 flex calculator.l # 3. 编译并链接所有文件,指定控制台模式 gcc lex.yy.c calculator.tab.c -o calculator -mconsole
编译完成后,运行calculator.exe即可输入表达式进行计算。
内容的提问来源于stack exchange,提问作者Farenhyte
相关产品推荐
相关产品推荐

