Search code examples
bison

Flex and Bison does not recognize character


I would like to make a simple calculator that computes values as 3+4 or 5/8, but I have a problem with the abs using the math function. My code is the following:

Bison file:

%{
#include <stdio.h>
#include <math.h>
%}

/* declare tokens */
%token NUMBER
%token ADD SUB MUL DIV ABS
%token EOL

%%
calclist: /* nothing */
    | calclist exp EOL { 
                printf("= %d\n", $2); 
               }
;

exp: factor     
    | exp ADD factor { $$ = $1 + $3; }
    | exp SUB factor { $$ = $1 - $3; }
;

factor: term        
    | factor MUL term { $$ = $1 * $3; }
    | factor DIV term { $$ = $1 / $3; }
;

term: NUMBER        
    | ABS term {$$=fabs($2)}    
;
%%
main(int argc, char **argv)
{
    yyparse();
}
yyerror(char *s)
{
    fprintf(stderr, "error: %s\n", s);
}

and the Flex file

%{
# include "calc.tab.h"
%}
/* recognize tokens for the calculator and print them out */

%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"@" { return ABS; }
[0-9]+ { yylval = atoi(yytext); 
    return NUMBER; 
    }
\n  { return EOL; }
[ \t]   { /* ignore whitespace */ }
.   { 
        printf("Mystery character %c\n", *yytext); 
    }
%%
yywrap()
{
}

I have selected the @ symbol for the absolute value, but my program does recognize expressions such as:

4+@5, but not like 4+@-5

What should I change in my program, so that it recognizes this operator?


Solution

  • It seems @ operator definition is proper. However, your language definition does not accept unary minus, i.e. your code cannot accept something like 4+-5 without @. You need to add appropriate language definitions to support unary minus. (and if you need, unary plus). For details on unary operators, and how they are different than binary operators, you may read Unary Operation on wiki.

    You may try something like:

    term: NUMBER        
        | ABS term {$$ = fabs($2); }    
        | SUB term {$$ = -$2; }        
    ;