2
votes

I'm trying to make a very simple calculator with flex and bison generators. It just work on integer numbers. I compiled the lexer file properly with no errors; but when I compile the parser file, it shows me some warnings:

  • warning: 1 nonterminal useless in grammar
  • warning: 2 rules useless in grammar
  • 21.1-4: warning: nonterminal useless in grammar: Line
  • 21.9-1: warning: rule useless in grammar: Line: NWL
  • 22.9-55: warning: 1 nonterminal useless in grammar: Exp NWL

It make the output file after showing these warnings.
I compiled the output files by gcc; it made an .exe file.
When I run the .exe file and try to calculate, it shows me this error:

  • syntax error

Please help me.

My codes:
lexer file

%option noyywrap
%{
#define YYSTYPE double
#include <stdio.h>
#include "x.tab.h"
%}
DIG         [0-9]
%%
{DIG}+      { yylval = atoi(yytext); return NUM; }
"+"                             { return PLS; }
"-"                             { return MNS; }
"*"                             { return MUL; }
"/"                             { return DIV; }
"\n"                                { return NWL; }
"("                             { return LFT; }
")"                             { return RIT; }
%%

parser file

%{
#include <stdio.h>
#define YYSTYPE double
int yyerror (char const *s);
extern int yylex (void);
%}
%token  PLS MNS
%token  MUL DIV
%token  NWL
%token  NUM
%token  LFT RIT
%left   PLS MNS
%left   MUL DIV
%%
Exp:    NUM             { $$ = $1; };
Exp:    Exp PLS Exp     { $$ = $1 + $3; };
Exp:    Exp MNS Exp     { $$ = $1 - $3; };
Exp:    Exp MUL Exp     { $$ = $1 * $3; };
Exp:    Exp DIV Exp     { $$ = $1 / $3; };
Exp:    LFT Exp RIT     { $$ = $2; };
Line:   NWL;
Line:   Exp NWL         { printf("%f\n", $1); };
;
%%
int yyerror(char const *s) {
  printf("%s\n", s);
}
int main(){
    int ret = yyparse();
    if (ret){
    fprintf(stderr, "%d error found.\n",ret);
    }
    return 0;
}
1
Are you surrounding the #define and #include statements with {...} ? (Top of each file.)ryyker
Were there any more details on the C syntax error ? what else did the error message say?ryyker
I think it's not C syntax error; Because when I write something in my calculator, it shows me this error: syntax error (not anymore).antoni
You need to look up the | operator of Yacc/Bison. What you have written is not a correct way of expressing alternate reductions to the same non-terminal.user207421
@user207421 It's correct; foo: bar; foo: qux is absolutely the same as foo: bar | qux. It's just a matter of style. Also, the order doesn't matter -- except for determining the start sym when not stated explicitly with %start sym.mosvy

1 Answers

3
votes

The start symbol of your grammar is Exp, not Line. Either put the Line rule first or use a %start Line declaration. The %start declaration should go before the %%, in the same section with the %token declarations.

That should get you at the point where your program could handle a first line like 3 + 4 ;-)

If you want it to handle multiple lines, you should add another rule -- example of a fixed grammar section of your *.y file, with Seq (sequence of lines) being the start symbol:

Seq:    /* empty */
|       Seq Line
Exp:    NUM             { $$ = $1; };
Exp:    Exp PLS Exp     { $$ = $1 + $3; };
Exp:    Exp MNS Exp     { $$ = $1 - $3; };
Exp:    Exp MUL Exp     { $$ = $1 * $3; };
Exp:    Exp DIV Exp     { $$ = $1 / $3; };
Exp:    LFT Exp RIT     { $$ = $2; };
Line:   NWL
Line:   Exp NWL         { printf("%f\n", $1); };