Search code examples
c++cparsingbisonyacc

Bison parser doesn't recognize the "New" keyword


I am trying to build a simple compiler and I am in the stage to test the Bison parser I created recently over some sample .decaf files, the parser works well with all keywords and the grammar's terminal and non-terminal tokens/types and rest of the grammar rules and actions, but there is only one problem that my parser does not recognize the New keyword/operator, when ever a statement includes a New keyword it results into an error in the output!

Defining New as a terminal token

%token   T_New

CFG grammar rule and action for Expr that also includes rule and action for T_New

Expr          :   LValue '=' Expr       { $$=new AssignExpr($1,new Operator(@2,"="),$3); }   
              |   '(' Expr ')'          { $$=$2; }
              |   Expr '+' Expr         { $$=new ArithmeticExpr($1,new Operator(@2,"+"),$3); }
              |   Expr '-' Expr         { $$=new ArithmeticExpr($1,new Operator(@2,"-"),$3); }
              |   Expr '*' Expr         { $$=new ArithmeticExpr($1,new Operator(@2,"*"),$3); }
              |   Expr '/' Expr         { $$=new ArithmeticExpr($1,new Operator(@2,"/"),$3); }
              |   Expr '%' Expr         { $$=new ArithmeticExpr($1,new Operator(@2,"%"),$3); }
              |   '-' Expr %prec T_UnaryMinus  { $$=new ArithmeticExpr(new Operator(@1,"-"),$2); }
              |   Expr T_And Expr       { $$=new LogicalExpr($1,new Operator(@2,"&&"),$3); }
              |   Expr T_Or Expr        { $$=new LogicalExpr($1,new Operator(@2,"||"),$3); }
              |   Expr '<' Expr         { $$=new RelationalExpr($1,new Operator(@2,"<"),$3); }
              |   Expr T_LessEqual Expr { $$=new RelationalExpr($1,new Operator(@2,"<="),$3); }
              |   Expr '>' Expr         { $$=new RelationalExpr($1,new Operator(@2,">"),$3); }
              |   Expr T_GreaterEqual Expr  { $$=new RelationalExpr($1,new Operator(@2,">="),$3); }
              |   Expr T_Equal Expr     { $$=new EqualityExpr($1,new Operator(@2,"=="),$3); }
              |   Expr T_NotEqual Expr  { $$=new EqualityExpr($1,new Operator(@2,"!="),$3); }
              |   '!' Expr              { $$=new LogicalExpr(new Operator(@1, "!"), $2); }
              |   T_ReadInteger '(' ')' { $$=new ReadIntegerExpr(@1); }
              |   T_ReadLine '(' ')'    { $$=new ReadLineExpr(@1); }
              |   T_New Identifier      { $$=new NewExpr(@2,new NamedType($2)); }
              |   T_NewArray '(' Expr ',' Type ')'  { $$=new NewArrayExpr(@1,$3,$5); }
              |   LValue                { $$=$1; }
              |   T_This                { $$=new This(@1); }
              |   Call                  { $$=$1; }
              |   Constant              { $$=$1; }
              ; 

for example I have this sample file interface.decaf for testing and it has a main function as below:

 void main() {
  Colorable s;
  Color green;

  green = New(Color);
  green.SetRGB(0, 0, 255);
  s = New(Rectangle);
  s.SetColor(green);
}

But when I run my parser over this sample file in the terminal I get this error:

    *** Error line 33.
green = New(Color);

*** syntax error

I tried with other sample files and noticed that any file that has a statement that mentions 'New' keyword returns the same error.

I got some hint from this question that probably New keyword is mixed up between C and C++ and that's why its not recognized by bison. but I am still not able to figure out how to fix this ! Can anyone help please ?


Solution

  • Your grammar has a rule

    | T_New Identifier        { ...
    

    matching a New keyword followed immediately by an identifier. However, your examples all have parenthesis around the identifier:

    green = New(Color)
    
    s = new(Rectangle)
    

    thus the syntax error you are seeing -- the input has a ( where the grammar expects an identifier...