1
votes

I'm testing the example of calculator implemented using bison and flex. The example code, in file "rpn-all-calc2.y", is:

%{
#define YYSTYPE double
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int yyerror(const char* s);
int yylex(void);
%}
%token NUM
%% /* grammer rules and actions follow */
input: /* empty */
    | input line
    ;
line: '\n'
    | exp '\n' { printf("\t%.10g\n", $1); }
    ;
exp: NUM { $$ = $1; }
    | exp exp '+' { $$ = $1 + $2; }
    | exp exp '-' { $$ = $1 - $2; }
    | exp exp '*' { $$ = $1 * $2; }
    | exp exp '/' { $$ = $1 / $2; }
    | exp exp '^' { $$ = pow($1, $2); }
    | exp 'n' { $$ = -$1; }
    ;
%%
#include <ctype.h>
int yylex(void)
{
int c;
while ((c = getchar()) == ' '||c == '\t') ; /* skip white spaces*/
if (c == '.' || isdigit(c)) /* process numbers */
{
ungetc(c, stdin);
scanf("%lf", &yylval);
printf("value is %lf\n",yylval);
return NUM;
}
if (c == EOF) return 0;
printf("symbol is %c, %d",c,c);
return c; }
int yyerror(const char* s) { printf("%s\n", s); return 0; }
int main(void) { return yyparse(); }

It works well. I want to use the flex + bison to implement this calculator as follows: the file "rp.lex":

%option noyywrap

%{
#include "rpn-all-calc3.tab.h"
%}

op  [+\-*/^n]+
ws  [ \t]+
letter [a-zA-Z]
digit [0-9]+

%%
{letter}   REJECT;
{digit} return NUM;
{op}|\n return *yytext;
{ws}    /* eat up white spaces */

%%

The file "rpn-all-calc2.y" is:

%{
#define YYSTYPE double
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int yyerror(const char* s);
int yylex(void);
%}
%token NUM
%% /* grammer rules and actions follow */
input: /* empty */
    | input line
    ;
line: '\n'
    | exp '\n' { printf("\t%.10g\n", $1); }
    ;
exp: NUM { $$ = $1; }
    | exp exp '+' { $$ = $1 + $2; }
    | exp exp '-' { $$ = $1 - $2; }
    | exp exp '*' { $$ = $1 * $2; }
    | exp exp '/' { $$ = $1 / $2; }
    | exp exp '^' { $$ = pow($1, $2); }
    | exp 'n' { $$ = -$1; }
    ;
%%
#include <ctype.h>
int main(void) { return yyparse(); }
int yyerror(const char* s) { printf("%s\n", s); return 0; }

There is no error in compiling:

bison -d rpn-all-calc2.y
flex -o rpn-all-calc3.lex.yy.c rp.lex
gcc *.c -o test -lm

But when I run "./test", I input, say: 1 1 + Then I got 0 No matter what equation I input, I always get 0. What's wrong with my code? Thank you all for helping me!!!

1

1 Answers

2
votes

In your Flex lexer, you forgot to set yylval to the number found.

You can change the line

{digit} return NUM;

to

{digit} { sscanf(yytext, "%lf", &yylval); return NUM; }