Flex / bison interprets numbers as floating

I am trying to implement a flex / bison calculator that can do floating point arithmetic. My flex code is as follows

%{ #include "calc.tab.h" #include <stdlib.h> void yyerror(char *s); %} digit [0-9] integer {digit}+ real ({digit}+[.]{digit}*)|({digit}*[.]{digit}+) exp ({integer}|{real})[eE]-?{integer} %% ({integer}|{real}|{exp}) { yylval = atof(yytext); return NUMBER; } [-+*/\n] { return *yytext; } [ \t\v\f\r] { } . { yyerror("Unknown Character"); } %% int yywrap(void) { return 1; } 

And my bison code looks like this

 %{ #include <stdio.h> typedef double YYSTYPE; #define YYSTYPE_IS_DECLARED void yyerror(char *s); extern char *yytext; extern int yylineno; %} %token NUMBER %left '+' '-' %left '*' '/' %% program: program expr '\n' { printf("%g\n", $2); } | program '\n' | ; expr: expr '+' expr { $$ = $1 + $3; } | expr '-' expr { $$ = $1 - $3; } | expr '*' expr { $$ = $1 * $3; } | expr '/' expr { $$ = $1 / $3; } | NUMBER { $$ = $1; } ; %% void yyerror(char *s) { fprintf(stderr, "error: %s at %s, line %d\n", s, yytext, yylineno); } int main(int argc, char *argv[]) { yyparse(); return 0; } 

This does not lead to the correct exit. Despite the fact that the lexer interprets the lines as doubled and stores them correctly in the yylval , when the parser sums the numbers, it spits out only 0.0000 . However, if I declare yylval as a union through the %union directive, which consists of only one double lf_val; variable double lf_val; and save the atof output in this yylval field in the lexer, and also declare %token <lf_val> NUMBER and %type <lf_val> expr everything works in the parser.

But why doesn't the simple typedef ing YYSTYPE method work? I also tried #define YYSTYPE double . That didn't work either.

+4
source share
1 answer

Regarding the %code , the Bison documentation says:

 %code requires [...] is the best place to override Bison default YYSTYPE and YYLTYPE definitions. 

So juste add the following at the top of the bison file:

 %code requires { #define YYSTYPE double } 

You will also want to delete these two lines:

 typedef double YYSTYPE; #define YYSTYPE_IS_DECLARED 

Please note that YYSTYPE_IS_DECLARED, as far as I know, is not documented anywhere and, therefore, is intended only for internal use of Bison.

If you are not familiar with using the Bison %code directives over simple %{ prologs, you may find this section of the documentation that you are interested in reading.

+5
source

All Articles