Steve
Steve

Reputation: 55

Bison error report interpretation

I have got the runtime message: syntax error, unexpected VARIABLE, expecting ':' or '\n' I suppose it is due to my wrong bison source, but what's the matter? In my lex source I have

'mod'       return MOD;
[-+()=/*\n:]    { return *yytext; }

but while a=55/4 runs fine, a=55mod4 exits with error report written before. Thanks forward for any appointment. Here is my full bison file:

%{
    #include <stdio.h>
    void yyerror(char *);
    int yylex(void);
    #include "y.tab.h"
    #include "bas.h"

    #define YYDEBUG 1
    #define YYERROR_VERBOSE 1
    #define YYTOKEN_TABLE 1
%}
%debug
%error-verbose
%token INTEGER VARIABLE PRINT
%left '+' '-'
%left '*' '/'
%left MOD
%%
program:
    program statement ':'       {
                        if (stackptr>0)
                            {
                            printf("stack underflow !\n");
                            }
                        else if (stackptr<0)
                            {
                            printf("stack overflow !\n");
                            }
                        }
    |
        program statement '\n'      {
                        if (stackptr>0)
                            {
                            printf("stack underflow !\n");
                            }
                        else if (stackptr<0)
                            {
                            printf("stack overflow !\n");
                            }
                        else    {
            /* send basictoken[] array to micro*/
                            printf("OK.\n");
                            debugprint();
                            }
                        resetbuffer();
                    stackptr=0;                     
                        }
        | /* NULL */
        ;
statement:
        expression
        | VARIABLE '=' expression       {
                        put_token(avr_tovar);
                        put_token($1);
                        stackptr--;
                        }
        | PRINT expression      {
                        put_token(avr_tos);
                        stackptr--;
                        }
        ;
expression:
    INTEGER             {
                    put_token(avr_const);
                    put_token(yylval);
                    stackptr++;
                        }
        | VARIABLE              {
                        put_token(avr_fromvar);
                        put_token(yyval);
                        stackptr++;
                            }
        | expression '+' expression     {
                        put_token(avr_add);                     
                        stackptr--;
                            }
        | expression '-' expression     {
                        put_token(avr_sub);                     
                        stackptr--;
                        }
        | expression '*' expression     {
                        put_token(avr_mul);                     
                        stackptr--;
                        }
        | expression '/' expression     {
                        put_token(avr_div);                     
                        stackptr--;
                        }
        | expression MOD expression     {
                        put_token(avr_mod);                     
                        stackptr--;
                        }
        | '(' expression ')'
        ;
%%
void yyerror(char *s)
{
    fprintf(stderr, "%s\n", s);
}

Upvotes: 3

Views: 278

Answers (2)

akim
akim

Reputation: 8759

Flex/lex does not support single quotes to denote strings, it uses double quotes to this end. So your scanner is actually waiting for you to enter a=55'mod'4. Either remove the single quotes, or use double quotes.

Also, don't use yylval in the parser's actions, use $1 and so forth. I don't know if your code works, but if it does, that's pure luck: yylval is about the lookahead, which does not need to be the same as the last of the reduced symbols.

Upvotes: 1

rici
rici

Reputation: 241721

My guess is that your lex file also has a rule like:

[[:digit:]]+             INTEGER
[[:alpha:]][[:alnum:]]*  VARIABLE

in which case MOD4 will be lexed as a VARIABLE and not as MOD because lex always chooses the longest match.

If you don't want to put a space after MOD in your input, you'll have to be much cleverer about how you specify VARIABLE.

Upvotes: 1

Related Questions