Search code examples
cbisonyacc

Parser error at 1: syntax error with yacc grammar


I have a simple grammar in yacc (bison):

expressions.y:

%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "../C_routines/SyntaxTree.h"

extern int yylineno;

int yylex();
void yyerror(const char *s);
int i=0;

typedef struct Exp {
    char *code;
    char *addr;
} Exp;
%}

%union {
    char *lexeme;
    char *value;
    double dvalue;
    struct SyntaxTree *Sy;
    int ivalue;
}

%type <Sy> E S
%token <lexeme> id ID 
%token <value> LITERAL
%token <dvalue> FLOAT
%token <ivalue> INT

%left '+' '-'
%left UMINUS

%%

S : id "=" E { $$ = newST('=',newid($1), $3); printSyntaxTree($$); }
  ;

E : E "+" E { $$ = newST('+', $1, $3); }
  | E "-" E { $$ = newST('-', $1, $3); }
  | "(" E ")" { $$ = $2; }
  | "-" E %prec UMINUS { $$ = newST(UMINUS, NULL, $2); }
  | id { $$ = newid($1); }
  | INT { $$ = newint($1); }
  | FLOAT { $$ = newdouble($1); }
  ;

%%

void yyerror(const char *s) {
    fprintf(stderr, "Parser error at %d: %s\n", yylineno, s);
}

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

lex:

%option yylineno

%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "../yacc/expressions.tab.h"
#include "../C_routines/SymbolTable.h"

%}

id [a-zA-Z_][a-zA-Z_0-9]*

INT [-]?[0-9]+
FLOAT [-]?[0-9]+([.][0-9]+)?([Ee][+-]?[0-9]+)?
bool "True" | "False"
str (\"([^\"\\\\]|\\\\.)*\")|('([^'\\\\]|\\\\.)*')

assign [+-/%*]?=
arith [+-/%*]


%%

{id} {
    printf("\nIdentifier : %s ", yytext);
    int a = installID(yytext, "ID");
    yylval.lexeme = strdup(yytext);
    return id;
}

{INT} {printf("\nInteger : %s ",yytext);
      int a = installLit(yytext,"INT");
      yylval.value = strdup(yytext);
      return INT;}

{str} {printf("String ");
      int a = installLit(yytext,"STR");
      yylval.value = strdup(yytext);
      return LITERAL;}

{FLOAT} {printf("Float ");
      int a = installLit(yytext,"FLOAT");
      yylval.value = strdup(yytext);
      return FLOAT;}

{assign} {printf("Assignment Operator\n");}
{arith} {printf("Arithmetic Operator\n");}


%%

int yywrap(){
  return 1;
}

When I run these:

Output 1

a=0

Identifier : a Assignment Operator

Integer : 0 Parser error at 1: syntax error

Output 2


a=b

Identifier : a Assignment Operator

Identifier : b Parser error at 1: syntax error

Output 3

a=-4

Identifier : a Assignment Operator

Integer : -4 Parser error at 1: syntax error

Output 4:

a=5+6

Identifier : a Assignment Operator

Integer : 5 Parser error at 1: syntax error

I have defined enough precedence and associativity for the operators and terminals. I couldn't figure out what is causing syntax error in line 1. Kindly help. I use flex for lex and bison for yacc

EDIT: adding #define YYERROR_VERBOSE 1 in declaration section gives,

Output 1:

a=0

Identifier : a Assignment Operator

Integer : 0 Parser error at 1: syntax error, unexpected INT, expecting =

Output 2:

a=a+b

Identifier : a Assignment Operator

Identifier : a Parser error at 1: syntax error, unexpected id, expecting =

Output 3:

a = b

Identifier : a  Assignment Operator

Identifier : b Parser error at 1: syntax error, unexpected id, expecting =

I gave = in my input but again it asks for = sign


Solution

  • Bison says that it doesn't receive "=" when expected and it isn't lying. Look into the lexer. That rule, which prints "Assignment operator", never returns anything. From the point of view of the parser, there is nothing there.

    Using printf for debugging is unreliable for such reasons. You should use proper ways to debug your lexer and parser.