使用Flex和Bison时遭遇“undefined reference to `yylval'”链接错误的解决求助
使用Flex和Bison时遭遇“undefined reference to `yylval'”链接错误的解决求助
问题还原
我在搭建一个极简的Flex+Bison整数减法解析程序时,卡在了链接阶段,一直弹出undefined reference to 'yylval'的错误。以下是我的代码、构建步骤和报错信息:
Lex词法分析器(lexer.l)
%{ #include "parser.tab.h" %} %% [0-9]+ { yylval = atoi(yytext); return NUMBER; } "-" {return MINUS;} %% int main () { yylex(); return 0; }
Bison语法分析器(parser.y)
%{ #include <stdio.h> #include <stdlib.h> void yyerror(const char* msg); int n=0; %} %token MINUS %token NUMBER %% program : NUMBER MINUS NUMBER { n=$1-$3 ; printf("%d\n",n);} %% void yyerror(const char* msg){ printf("%s\n", msg); } int main() { printf("Enter "); yyparse(); // Start parsing return 0; }
执行的构建命令
C:\Users\User\Desktop\workbench\prevodiocip\nnn>bison -d parser.y C:\Users\User\Desktop\workbench\prevodiocip\nnn>flex lexer.l C:\Users\User\Desktop\workbench\prevodiocip\nnn>gcc -o parser.tab.c lex.yy.c -lfl
最终的链接错误
C:\Users\User\AppData\Local\Temp\ccOvWXJo.o:lex.yy.c:(.text+0x1b1): undefined reference to `yylval' collect2.exe: error: ld returned 1 exit status
我尝试了各种办法都没解决,希望能得到大佬们的帮助!
问题根源与解决方案
别慌,这个错误的核心其实是编译命令的参数顺序和用法错误,再加上一个小的代码冗余问题,我们一步步来修复:
1. 修正GCC编译命令(最关键的一步)
你当前的gcc命令犯了一个典型错误:-o参数后面应该跟生成的可执行文件名,而不是源文件名!你写的gcc -o parser.tab.c lex.yy.c -lfl会让GCC把parser.tab.c当成输出文件来生成,而只编译lex.yy.c这一个源文件——但yylval的定义是在Bison生成的parser.tab.c里的,这个文件根本没被加入编译,自然会出现未定义引用的错误。
正确的编译命令应该是:
gcc parser.tab.c lex.yy.c -o calc -lfl
参数解释:
parser.tab.c:Bison生成的解析器代码,包含yylval的定义lex.yy.c:Flex生成的词法分析器代码,引用了yylval-o calc:指定最终生成的可执行文件名为calc(你可以改成任意喜欢的名字)-lfl:链接Flex的运行时库
2. 移除Lexer中冗余的main函数
你的lexer.l里定义了一个main函数,而parser.y里也有一个main函数,这会导致后续链接时出现“multiple definition of main'”的新错误。因为我们是通过Parser里的yyparse()`来启动整个解析流程的,Lexer不需要单独的main函数,直接删掉即可。
修改后的lexer.l:
%{ #include "parser.tab.h" %} %% [0-9]+ { yylval = atoi(yytext); return NUMBER; } "-" {return MINUS;} %% // 删掉原来的main函数块
3. 完整的重新构建流程
现在按照以下顺序重新执行命令,就能正常编译运行了:
- 生成带头文件的Bison解析器:
bison -d parser.y
- 生成Flex词法分析器:
flex lexer.l
- 编译链接生成可执行文件:
gcc parser.tab.c lex.yy.c -o calc -lfl
验证运行
执行生成的calc.exe,输入类似10-3这样的表达式,就能得到正确的计算结果啦。
内容来源于stack exchange
相关产品推荐
相关产品推荐

