-3

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 ?

Hashmatullah Noorzai
  • 771
  • 3
  • 12
  • 34
  • 1
    Yes @Walter I was talking about `new`, but the sample files I have for this project it uses the `New` (first letter cap) as you can see it in the code snippet from the file – Hashmatullah Noorzai Feb 24 '18 at 01:07
  • 1
    Is your lexical analyzer returning the token `T_New` at some point? Perhaps you've forgotten to add the rule in bison when a `T_new` is found? – Pablo Feb 24 '18 at 01:09
  • @Pablo yes my lexical scanner returns `New` as a token. I just rechecked it and tested a file that has the New in it, and it returned +ve, see below the result: `return line 12 cols 1-6 is T_Return New line 13 cols 1-3 is T_New ` – Hashmatullah Noorzai Feb 24 '18 at 01:19
  • 1
    If your lexer is returning the token, then the only thing I can think of is that you either don't have a rules in your bison file to match the token, or your rule is incorrect. – Pablo Feb 24 '18 at 01:22
  • @Pablo This is how I defined New in my parser.y file `Expr : T_New Identifier { $$=new NewExpr(@2,new NamedType($2)); }` – Hashmatullah Noorzai Feb 24 '18 at 01:24
  • 1
    And what is `Identifier`? Does it match `(`, `Color`, `)`? – Pablo Feb 24 '18 at 01:29
  • 2
    Well, the rule `Expr : T-New Identifier` won't match `New(Name)` because of the parentheses. That information should be in the question (the fragment of syntax) — there's no way we can diagnose what you're doing wrong if you're making that sort of mistake and not showing us the grammar. Read about how to create an MCVE ([MCVE]). It is harder with Bison + Flex ([tag:flex-lexer]), but… – Jonathan Leffler Feb 24 '18 at 01:29
  • 1
    Looks like your expect someone to figure out what's wrong with your lexer and/or the context-free bison/yacc grammar, without showing a single line of your lexer, and actual grammar spec. If someone is actually able to do that, I'll be quite impressed. – Sam Varshavchik Feb 24 '18 at 01:32
  • @SamVarshavchik I added the grammar – Hashmatullah Noorzai Feb 24 '18 at 01:42
  • 1
    It should be `| T_New '(' Identifier ')' { your code }` – Pablo Feb 24 '18 at 02:33
  • @Pablo Thank you got it already from your 3rd comment and corrected my grammar. :) – Hashmatullah Noorzai Feb 24 '18 at 02:36

1 Answers1

1

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...

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226