Compiler construction lex程序中对yylval的未定义引用
我正在处理Lex和Yacc程序,但我得到的错误如下: /tmp/ccTP9YY1.o:在函数Compiler construction lex程序中对yylval的未定义引用,compiler-construction,flex-lexer,lex,Compiler Construction,Flex Lexer,Lex,我正在处理Lex和Yacc程序,但我得到的错误如下: /tmp/ccTP9YY1.o:在函数yylex'中: lex.yy.c:(.text+0x289):未定义对yylval'的引用 lex.yy.c:(.text+0x2a8):对“yylval”的未定义引用 collect2:错误:ld返回了1个退出状态 我在互联网上搜索了很多,比如stackoverflow和其他网站,但似乎没有一个能解决我的问题。我可能没有正确地实施这些建议。有人能给我提些建议吗? 提前谢谢 %{ #include &l
yylex'中:
lex.yy.c:(.text+0x289):未定义对
yylval'的引用
lex.yy.c:(.text+0x2a8):对“yylval”的未定义引用
collect2:错误:ld返回了1个退出状态
我在互联网上搜索了很多,比如stackoverflow和其他网站,但似乎没有一个能解决我的问题。我可能没有正确地实施这些建议。有人能给我提些建议吗?
提前谢谢
%{
#include <stdlib.h>
#include "y.tab.h"
void yyerror(char *);
%}
%%
[a-z] {
yylval = *yytext - 'a';
return VARIABLE;
}
[0-9]+ {
yylval = atoi(yytext);
return INTEGER;
}
[-+()=/*\n] { return *yytext; }
[ \t] ;
. { yyerror("invalid character"); }
%%
void yyerror(char *s) {
fprintf(stderr, "%s\n", s);
}
int yywrap(void) {
return 1;
}
Yacc文件:
%token INTEGER VARIABLE
%left '+' '-'
%left '*' '/'
%{
void yyerror(char *);
int yylex(void);
int sym[26];
%}
%%
program:
program statement '\n'
|
;
statement:
expr { printf("%d\n", $1); }
| VARIABLE '=' expr { sym[$1] = $3; }
;
expr:
INTEGER
| VARIABLE { $$ = sym[$1]; }
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { $$ = $1 / $3; }
| '(' expr ')' { $$ = $2; }
;
%%
void yyerror(char *s) {
fprintf(stderr, "%s\n", s);
}
int main(void) {
yyparse();
return 0;
}
Yacc(和Bison)生成两个文件,即
y.tab.h
和y.tab.c
,前提是您不使用选项-o
覆盖输出文件。在源代码中包含y.tab.h
,并编译y.tab.c
。因此,可能您在尝试编译时输入了一个错误:
gcc lex.yy.c y.tab.c -ll
-------------------^-------- compile y.tab.c, not y.tab.h
您应该编译
.c
文件,而不是.h
文件。以下是编译lex和yacc程序所需的命令:
1. yacc -d yaccCalc.y
2. lex echo.l
3. cc lex.yy.c y.tab.c -ll -ly
您需要将扫描器与解析器链接(因为解析器中定义了
yylval
)。我肯定其他答案都是这么说的,但是如果你不透露你用来编译和链接你的项目的确切命令,就不可能知道你在试图完成它时犯了什么错误。现在,我已经使用命令和yacc文件在gcc
命令中将y.tab.h
更改为y.tab.c
。编译头文件并不会执行您认为它可以执行的操作,即使它执行了,也不会有帮助,因为头文件中没有yylval
的定义,只有声明。(您已经#包括在lex.yy.c
中生成的头文件,因此声明了yylval
。链接器错误是因为它从未定义过。)请为您的答案添加解释。完成。我应该解释一下。
1. yacc -d yaccCalc.y
2. lex echo.l
3. cc lex.yy.c y.tab.c -ll -ly