1
votes

I am writing a nor calculator using Flex and Bison. Here is my .l file:

%{
#include <stdlib.h>
#include "y.tab.h"
%}

%% 
("true"|"false")    {return BOOLEAN;}
"nor"               {return NOR;}
.                   {return yytext[0];}

%%

int main(void)
{
    yyparse();
    return 0;
}

int yywrap(void)
{
     return 0;
}
int yyerror(void)
{
    getchar();
    printf("Error\n");
}

Here is my .y file:

/* Bison declarations.  */
 %token BOOLEAN
 %token NOR
 %left 'nor'

 %% /* The grammar follows.  */
 input:
   /* empty */
 | input line
 ;

 line:
   '\n'
 | exp '\n'  { printf ("%s",$1); }
 ;

 exp:
   BOOLEAN            { $$ = $1;           }
 | exp 'nor' exp      { $$ = !($1 || $3);  }
 | '(' exp ')'        { $$ = $2;           }
 ;
 %%

The problem is that if I type an input such as "true nor false", the lexer only gets to return BOOLEAN, then return yytext[0], then throws my error (in the flex code). Anyone see what's wrong?

2
Sorry, I meant my error - the one in my flex code. - John Roberts
I removed the Flex tag (which is used for the Adobe/Apache UI Framework) and replaced it w/ gnu-flex which is used for the lexical analyzer. - JeffryHouser
Since flex has a rule to return NOR when it sees "nor", your bison exp clause for that case should be exp NOR exp, I think. Also, in the BOOLEAN case, you're not converting the associated string to an actual boolean value, so later when you try to calculate the result, it's not doing what you think it is. There's probably more... - twalberg
Substituting exp NOR exp allowed me to get to all the tokens, but now I get the message "conflicts: 1 shift/reduce". Any clue what's causing that? - John Roberts

2 Answers

1
votes

the problem is here :

%left 'nor'

and

exp:
   BOOLEAN            { $$ = $1;           }
 | exp 'nor' exp      { $$ = !($1 || $3);  }
 | '(' exp ')'        { $$ = $2;           }
 ;

you'v written 'nor' as a terminal token, your parser can't recognize 'nor' as token, so you should substitute this by NOR as the lexer returns:

"nor"               {return NOR;}

solution

    %left NOR

and 

    exp:
       BOOLEAN            { $$ = $1;           }
     | exp NOR exp      { $$ = !($1 || $3);  }
     | '(' exp ')'        { $$ = $2;           }
     ;
0
votes

Your lexer also needs to recognize white space. Make another rule " ". You don't need an action