Lex/Yacc实现新编程语言时遇line_num未定义引用错误求助
问题场景与报错
我最近被指派用Lex和Yacc实现一门新编程语言,写了下面这部分Yacc代码,原本期望它能输出语法错误以及对应的行号:
// 其余代码 %% #include "lex.yy.c" extern int line_num; main() { return yyparse(); } void yyerror( char *s ) { fprintf(stderr,"Syntax Error in line: %d\n%s\n",line_num, s); }
结果编译时,编译器抛出了链接错误:
/tmp/cclW8fn4.o: In function
yyerror': y.tab.c:(.text+0x200f): undefined reference toline_num'
collect2: error: ld returned 1 exit status
问题原因与解决办法
这个错误的核心是:line_num只在Yacc代码里被声明为extern(表示该变量在其他文件定义),但Lex代码里并没有实际定义这个变量,或者行号递增的逻辑没做,导致链接器找不到它的具体实现。
具体解决步骤如下:
- 在Lex文件中定义行号变量
在你的.l文件开头添加变量定义,初始化行号为1:int line_num = 1; - 在Lex规则中处理换行,递增行号
在Lex的匹配规则里加上对换行符的处理,确保每遇到一行就更新行号:"\n" { line_num++; } - 确保编译链接流程正确
如果是分开编译Lex和Yacc文件,要把两者的目标文件一起链接,比如执行以下命令:lex your_lex_file.l yacc -d your_yacc_file.y gcc lex.yy.c y.tab.c -o your_program
这样修改后,链接器就能找到line_num的定义,程序也能正常输出错误对应的行号了。
内容的提问来源于stack exchange,提问作者user8763792




