I am working through the O'Reilly Flex & Bison book by John Levine and I have encountered the following problem while attempting to compile and run the example for a simple BNF calculator
> ./fb1-5
2 + 3 * 4
= 0
2 * 3 + 4
= 0
c
Mystery Character c
error: syntax error
The program seems to recognize non-numerical input and exit accordingly, however any integer inputs with a mult/div/add/sub expression always result in the constant output of zero.
I have searched for similar questions on stack overflow as well as read through the chapter in O'Reilly multiple times. I am also in the process of mining through http://dinosaur.compilertools.net/bison/bison_5.html to try and find my mistake. Thanks for overlooking my bewilderment in the face of a seemingly elementary obstacle. I'm just getting started on my self journey through compilers. Any advice is appreciated.
flex (fb1-5.L):
%{
#include "fb1-5.tab.h" /*forward declaration - not yet compiled*/
%}
%%
"+" {return ADD;}
"-" {return SUB;}
"*" {return MUL;}
"/" {return DIV;}
[0-9]+ { yylval = atoi(yytext); return NUMBER;}
\n { return EOL;}
[ \t] { } /*ignore whitespace*/
. { printf("Mystery Character %c\n", *yytext);}
%%
bison (fb1-5.y):
%{
#include <stdio.h>
%}
/*declare tokens*/
%token NUMBER
%token ADD
%token SUB
%token MUL
%token DIV
%token ABS
%token EOL
/*BNF tree*/
%%
calclist: /*nothing - matches at beginning of input*/
| calclist exp EOL { printf("= %d\n", $1);}
;
exp: factor /*default $$ = $1*/
| exp ADD factor { $$ = $1 + $3;}
| exp SUB factor { $$ = $1 - $3;}
;
factor: term /*default $$=$1*/
| factor MUL term { $$ = $1 * $3;}
| factor DIV term { $$ = $1 / $3;}
;
term: NUMBER /*default $$=$1*/
| ABS term { $$ = $2 >= 0 ? $2 : - $2;}
;
%%
int main(int argc, char **argv)
{
yyparse();
return 0;
}
yyerror(char *s)
{
fprintf(stderr, "error: %s\n", s);
}
Makefile:
fb1-5: fb1-5.l fb1-5.y
bison -d fb1-5.y
flex fb1-5.l
gcc -o $@ fb1-5.tab.c lex.yy.c -lfl
clean:
rm -f core fb1-5.tab.h fb1-5.tab.c lex.yy.c fb1-5
printf("= %d\n", $1);
Should be
printf("= %d\n", $2);
Since exp
is the second thing on the right-hand side of that production.