Reputation: 99498
I am trying to compile an example from book flex and Bison
. I was wondering why I got the following build error, and how I can correct it?
$ 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
Makefile:
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> ", $2); }
| calclist EOL { printf("> "); } /* blank line or a comment */
;
exp: factor
| exp ADD exp { $$ = $1 + $3; }
| exp SUB factor { $$ = $1 - $3; }
| exp ABS factor { $$ = $1 | $3; }
;
factor: term
| factor MUL term { $$ = $1 * $3; }
| factor DIV term { $$ = $1 / $3; }
;
term: NUMBER
| ABS term { $$ = $2 >= 0? $2 : - $2; }
| OP exp CP { $$ = $2; }
;
%%
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); }
%%
Upvotes: 3
Views: 2947
Reputation: 18410
You have to change your makefile to:
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
to produce the correct output file and have a standard implementation of yyerror
Upvotes: 3
Reputation: 241861
There are two separate issues here.
yyerror
is not declared in your scanner (or, for that mattet in your parser). Bison does not generate a declaration for it so you need to declare it in any translation unit which uses it.
cc -o fb1-5.tab.c lex.yy.c -lfl
tells the C compiler to compile lex.yy.c
placing the resulting executable (the output of the compiler) into fb1-5.tab.c
. That's not what you intended. It overwrites the generated parser with an executable, and does not compile the generated parser with the result that symbols defined in the parser are not available to the linker.
Upvotes: 2
Reputation: 2080
I suppose that the problem is here
cc -o lex.yy.c fb1-5.tab.c -lfl
Upvotes: 2