HDFighter
HDFighter

Reputation: 25

Bison syntax error

I recently started learning bison and I already hit a wall. The manual sections are a little bit ambiguous, so I guess an error was to be expected. The code below is the first tutorial from the official manual - The Reverse Polish Notation Calculator, saved in a single file - rpcalc.y.

/* Reverse polish notation calculator */

%{
    #include <stdio.h>
    #include <math.h>
    #include <ctype.h>
    int yylex (void);
    void yyerror (char const *);
%}

%define api.value.type {double}
%token NUM

%% /* Grammar rules and actions follow. */

input:
    %empty
|   input line
;

line:
    '\n'
|   exp '\n'    {printf ("%.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;         }
;
%%

/* The lexical analyzer */

int yylex (void)
{
    int c;

    /* Skip white space */
    while((c = getchar()) == ' ' || c == '\t')
        continue;
    /* Process numbers */
    if(c == '.' || isdigit (c))
    {
        ungetc (c, stdin);
        scanf ("%lf", $yylval);
        return NUM;
    }
    /* Return end-of-imput */
    if (c == EOF)
        return 0;
    /* Return a single char */
    return c;
}

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

void yyerror (char const *s)
{
    fprintf (stderr, "%s\n", s);
}

Executing bison rpcalc.y in cmd returns the following error:

rpcalc.y:11.24-31: syntax error, unexpected {...}

What seems to be the problem?

Upvotes: 2

Views: 1212

Answers (1)

The fault is caused by you using features that are new to the 3.0 version of bison, whereas you have an older version of bison installed. If you are unable to upgrade to version 3.0, it is an easy change to convert the grammar to using the features of earlier versions of bison.

The %define api.value.type {double} can be changed to a %type command, and the %empty command removed. The resulting bison program would be:

/* Reverse polish notation calculator */

%{
    #include <stdio.h>
    #include <math.h>
    #include <ctype.h>
    int yylex (void);
    void yyerror (char const *);
%}

%type <double> exp
%token <double> NUM

%% /* Grammar rules and actions follow. */

input:
|   input line
;

line:
    '\n'
|   exp '\n'    {printf ("%.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;         }
;
%%

/* The lexical analyzer */

int yylex (void)
{
    int c;

    /* Skip white space */
    while((c = getchar()) == ' ' || c == '\t')
        continue;
    /* Process numbers */
    if(c == '.' || isdigit (c))
    {
        ungetc (c, stdin);
        scanf ("%lf", $yylval);
        return NUM;
    }
    /* Return end-of-imput */
    if (c == EOF)
        return 0;
    /* Return a single char */
    return c;
}

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

void yyerror (char const *s)
{
    fprintf (stderr, "%s\n", s);
}

This runs in a wider range of bison versions.

Upvotes: 1

Related Questions