对“yylval”和“yyerror”的未定义引用
Undefined reference to `yylval' and `yyerror`
我正在尝试编译 flex and Bison
书中的示例。我想知道为什么会出现以下构建错误,我该如何更正它?
$ make
bison -d fb1-5.y
fb1-5.y: warning: 3 shift/reduce conflicts [-Wconflicts-sr]
flex fb1-5.l
cc -o fb1-5.tab.c lex.yy.c -lfl
fb1-5.l: In function ‘yylex’:
fb1-5.l:27:3: warning: implicit declaration of function ‘yyerror’; did you mean ‘perror’? [-Wimplicit-function-declaration]
. { yyerror("Mystery character %c\n", *yytext); }
^~~~~~~
perror
/tmp/cctl5WLj.o: In function `yylex':
lex.yy.c:(.text+0x32f): undefined reference to `yylval'
lex.yy.c:(.text+0x363): undefined reference to `yyerror'
collect2: error: ld returned 1 exit status
Makefile:2: recipe for target 'fb1-5' failed
make: *** [fb1-5] Error 1
生成文件:
fb1-5: fb1-5.l fb1-5.y
bison -d fb1-5.y
flex fb1-5.l
cc -o fb1-5.tab.c lex.yy.c -lfl
fb1-5.y
/* simplest version of calculator */
%{
# include <stdio.h>
%}
/* declare tokens */
%token NUMBER
%token ADD SUB MUL DIV ABS
%token OP CP
%token EOL
%%
calclist: /* nothing */
| calclist exp EOL { printf("= %d\n> ", ); }
| calclist EOL { printf("> "); } /* blank line or a comment */
;
exp: factor
| exp ADD exp { $$ = + ; }
| exp SUB factor { $$ = - ; }
| exp ABS factor { $$ = | ; }
;
factor: term
| factor MUL term { $$ = * ; }
| factor DIV term { $$ = / ; }
;
term: NUMBER
| ABS term { $$ = >= 0? : - ; }
| OP exp CP { $$ = ; }
;
%%
main()
{
printf("> ");
yyparse();
}
yyerror(char *s)
{
fprintf(stderr, "error: %s\n", s);
}
fb1-5.l:
/* recognize tokens for the calculator and print them out */
%{
# include "fb1-5.tab.h"
%}
%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"|" { return ABS; }
"(" { return OP; }
")" { return CP; }
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
\n { return EOL; }
"//".*
[ \t] { /* ignore white space */ }
. { yyerror("Mystery character %c\n", *yytext); }
%%
我想问题出在这里
cc -o lex.yy.c fb1-5.tab.c -lfl
这里有两个不同的问题。
yyerror
未在您的扫描器中声明(或者,对于您的解析器中的那个 mattet)。 Bison 不会为其生成声明,因此您需要在使用它的任何翻译单元中声明它。
cc -o fb1-5.tab.c lex.yy.c -lfl
告诉 C 编译器编译 lex.yy.c
并将生成的可执行文件(编译器的输出)放入 fb1-5.tab.c
。那不是你想要的。它用可执行文件覆盖生成的解析器,并且不编译生成的解析器,结果解析器中定义的符号对链接器不可用。
您必须将 makefile 更改为:
fb1-5: fb1-5.l fb1-5.y
bison -b fb1-5 -d fb1-5.y
flex fb1-5.l
gcc -o fb1-5 fb1-5.tab.c lex.yy.c -lfl -ly
生成正确的输出文件并具有 yyerror
的标准实现
我正在尝试编译 flex and Bison
书中的示例。我想知道为什么会出现以下构建错误,我该如何更正它?
$ make
bison -d fb1-5.y
fb1-5.y: warning: 3 shift/reduce conflicts [-Wconflicts-sr]
flex fb1-5.l
cc -o fb1-5.tab.c lex.yy.c -lfl
fb1-5.l: In function ‘yylex’:
fb1-5.l:27:3: warning: implicit declaration of function ‘yyerror’; did you mean ‘perror’? [-Wimplicit-function-declaration]
. { yyerror("Mystery character %c\n", *yytext); }
^~~~~~~
perror
/tmp/cctl5WLj.o: In function `yylex':
lex.yy.c:(.text+0x32f): undefined reference to `yylval'
lex.yy.c:(.text+0x363): undefined reference to `yyerror'
collect2: error: ld returned 1 exit status
Makefile:2: recipe for target 'fb1-5' failed
make: *** [fb1-5] Error 1
生成文件:
fb1-5: fb1-5.l fb1-5.y
bison -d fb1-5.y
flex fb1-5.l
cc -o fb1-5.tab.c lex.yy.c -lfl
fb1-5.y
/* simplest version of calculator */
%{
# include <stdio.h>
%}
/* declare tokens */
%token NUMBER
%token ADD SUB MUL DIV ABS
%token OP CP
%token EOL
%%
calclist: /* nothing */
| calclist exp EOL { printf("= %d\n> ", ); }
| calclist EOL { printf("> "); } /* blank line or a comment */
;
exp: factor
| exp ADD exp { $$ = + ; }
| exp SUB factor { $$ = - ; }
| exp ABS factor { $$ = | ; }
;
factor: term
| factor MUL term { $$ = * ; }
| factor DIV term { $$ = / ; }
;
term: NUMBER
| ABS term { $$ = >= 0? : - ; }
| OP exp CP { $$ = ; }
;
%%
main()
{
printf("> ");
yyparse();
}
yyerror(char *s)
{
fprintf(stderr, "error: %s\n", s);
}
fb1-5.l:
/* recognize tokens for the calculator and print them out */
%{
# include "fb1-5.tab.h"
%}
%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"|" { return ABS; }
"(" { return OP; }
")" { return CP; }
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
\n { return EOL; }
"//".*
[ \t] { /* ignore white space */ }
. { yyerror("Mystery character %c\n", *yytext); }
%%
我想问题出在这里
cc -o lex.yy.c fb1-5.tab.c -lfl
这里有两个不同的问题。
yyerror
未在您的扫描器中声明(或者,对于您的解析器中的那个 mattet)。 Bison 不会为其生成声明,因此您需要在使用它的任何翻译单元中声明它。cc -o fb1-5.tab.c lex.yy.c -lfl
告诉 C 编译器编译lex.yy.c
并将生成的可执行文件(编译器的输出)放入fb1-5.tab.c
。那不是你想要的。它用可执行文件覆盖生成的解析器,并且不编译生成的解析器,结果解析器中定义的符号对链接器不可用。
您必须将 makefile 更改为:
fb1-5: fb1-5.l fb1-5.y
bison -b fb1-5 -d fb1-5.y
flex fb1-5.l
gcc -o fb1-5 fb1-5.tab.c lex.yy.c -lfl -ly
生成正确的输出文件并具有 yyerror
的标准实现