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.
source share