1

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; } 
5
  • Are you surrounding the #define and #include statements with {...} ? (Top of each file.) Commented Jan 10, 2020 at 13:56
  • Were there any more details on the C syntax error ? what else did the error message say? Commented Jan 10, 2020 at 14:00
  • 1
    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). Commented Jan 10, 2020 at 14:04
  • 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. Commented Jan 28, 2020 at 6:33
  • @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. Commented Jan 29, 2020 at 2:12

1 Answer 1

3

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); }; 
Sign up to request clarification or add additional context in comments.

4 Comments

It is recommended to use %empty to make explicit that a rule RHS is empty. Much like using ε in formal language theory.
@akim %empty is bison-only. I'll put a comment instead.
(The question was about Bison and Flex.)
still don't see any reason to use extensions unless necessary -- unlike other bison features like location tracking and reentrancy support, that %empty directive doesn't add much value.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.