title: Precedence and Associativity - Grammar Mistake using JavaCC
body: <p>I'm having a problem with my grammar and I don't really know how to solve it. I'm facing the issue with precedence and associativity in operations. I included the whole grammar but I avoided to put all the Tokens otherwise it'd be too long.</p>
  
  <pre>
  PARSER_BEGIN(UcParse) 
  
  Node Start() : 
  {
    Node tree = new Node(Id.PROGRAM);
    Node td;
  }
  {
      ( td = TopLevelDeclaration() { tree.add(td); }
      )*
      &lt;EOF> { return tree; }
  }
  
  Node TopLevelDeclaration() : 
  {
    Node n;
  }
  {
    LOOKAHEAD(3)
    n = Declaration() &lt;SEMI> { return n; } 
    | n = Function() { return n; }
    | n = IncludeFile() {return n; }
  }
  
  Node Function() :
  {
    Node tld = new Node(Id.FUNC);
    Node bt;
    Node dr;
    Node body;
    Node formals;
    Node s;
  }
  {
    bt = ReturnType() { tld.add(bt); }
      Declarator(tld)
      (
        FunctionParameters(tld)
        (
          body = CompoundStatement() { tld.add(body); }
        | 
          &lt;SEMI>
        ) 
      | { }
      )
  
    { return tld; }
  }
  
  //List FunctionParameters () :
  void FunctionParameters (Node func) :
  { 
    Node f;
  }
  { 
    &lt;LPAREN> 
    (
      &lt;VOID> { func.add(new Node(Id.VOID)); } 
    |
      f = Declaration() { func.add(f); }
      ( &lt;COMMA>
        f = Declaration() { func.add(f); }
      )*
    )
    &lt;RPAREN>
  }
  
  Node Declaration () :
  {
    Node d = new Node(Id.VARDEC);
    Node bt;
    Node dr;
  }
  {
    bt = DeclarationType() { d.add(bt); }
    Declarator(d) { return d; }
  }
  
  Node SimpleDeclaration () : 
  {
    Node d = new Node(Id.VARDEC);
    Node bt;
    Node id;
  }
  {
    bt = DeclarationType() { d.add(bt); }
    id = Identifier() { d.add(id); }
    &lt;SEMI>
    { return d; }
  }
  
  Node ReturnType () :
  {}
  {
    &lt;CHAR> { return new Node(Id.CHAR); }
  | &lt;INT> { return new Node(Id.INT); }
  | &lt;VOID> { return new Node(Id.VOID); }
  }
  
  Node DeclarationType () :
  {}
  {
    &lt;CHAR> { return new Node(Id.CHAR); }
  |
    &lt;INT> { return new Node(Id.INT); }
  }
  
  void Declarator (Node p) :
  { 
    Node id;
    Node r;
  }
  {
    id = Identifier() { p.add(id); }
    ( &lt;LBRACK>
      ( r = IntegerLiteral() { p.add(r); } ) *
      &lt;RBRACK>
    |
    { }
    )
  }
  
  Node CompoundStatement () :
  {
    Node cs = new Node(Id.COMPOUND_STMNT);
    Node d;
    Node s;
  }
  {
    &lt;LBRACE>
    ( d = Declaration() { cs.add(d); }
      &lt;SEMI>
    )*
    ( s = Statement() { cs.add(s); }
    )*
    &lt;RBRACE>
  
    { return cs; }
  }
  
  Node Statement() :
  {
    Node stmt = new Node(Id.STMNT);
    Node s;
    Token t;
    Node c;
    Node s1;
    Node s2;
  }
  {
    (s = SimpleCompoundStatement() { stmt.add(s); }
  |
    Expression(stmt)
    &lt;SEMI> // expr;
  |
    &lt;SEMI> { stmt.add(new Node(Id.EMPTY_STMNT)); } //;
  |
    t =  { s = new Node(Id.IF); stmt.add(s); }
    &lt;LPAREN>
    Expression(s)
    &lt;RPAREN>
    s1 = Statement() { s.add(s1); }
    ( LOOKAHEAD(1)
      &lt;ELSE>
      s2 = Statement() { s.add(s2); } ) *
  | 
    t = &lt;WHILE> { s = new Node(Id.WHILE); stmt.add(s); }
    &lt;LPAREN>
    Expression(s)
    &lt;RPAREN>
    s2 = Statement() { s.add(s2); }
  |
    
    (Expression(stmt)) *
    &lt;SEMI>) //return expr*;
  
    { return stmt; }
  }
  
  Node SimpleCompoundStatement() :
  {
    Node scs = new Node(Id.SIMPLE_COMPOUND_STMNT);
    Token left;
    Token right;
    Node s;
  }
  {
    left = &lt;LBRACE> 
    ( s = Statement() { scs.add(s); }
    )*
    right = &lt;RBRACE>
  
    { return scs; }
  }
  
  void Expression (Node e) :
  {
    Node exp;
    Node id;
    Node p;
    Node op;
  }
  { 
    (
      op = IntegerLiteral()
      OperatorExpression(e, op)
  |
      exp = CharLiteral()
      OperatorExpression(e, exp)
  
  |
    &lt;LPAREN> { p = new Node(Id.PAREN); }
    Expression(p)
    &lt;RPAREN>
    OperatorExpression(e, p)  
  
  | id = Identifier()
    ( &lt;LBRACK>
      Expression(e)
      &lt;RBRACK>
    | &lt;LPAREN>
      (
        Expression(e)
        ( &lt;COMMA>
          Expression(e)
        )*
      | { } )
      &lt;RPAREN>
    | {  }
    )
    OperatorExpression(e, id)
  |
    exp = Unary()
    Expression(e)
    OperatorExpression(e, exp)
    )
  }
  
  void OperatorExpression(Node par, Node op) :
  {
    Node n;
    Node p;
  }
  {
    ( LOOKAHEAD(2)
      n = BinaryMulDiv() { par.add(n); } 
      { n.add(op); }
      Expression(n) 
    | OperatorExpressionPlusMin(par, op) )
  }
  
  void OperatorExpressionPlusMin(Node par, Node op) :
  {
    Node n;
  }
  {
    ( LOOKAHEAD(2)
      n = BinaryPlusMin() { par.add(n); } 
      { n.add(op); }
      Expression(n)
    | OperatorExpressionComp(par, op))
  }
  
  void OperatorExpressionComp(Node par, Node op) :
  {
    Node n;
  }
  {
    ( LOOKAHEAD(2)
      n = BinaryComp() { par.add(n); } 
      { n.add(op); }
      Expression(par) 
    | {} {par.add(op);} )
  }
  
  Node BinaryComp () :
  {
    Token t;
  }
  {
    (t = &lt;LT> // >
  | 
    t = &lt;GT> //  //  // >=
  |
    t = &lt;EQ> // =
  |
    t = &lt;EQEQ> // ==
  | 
    t = &lt;NOTEQ> // !=
  | 
    t = &lt;ANDAND> // &&
  | 
    t = &lt;OROR>) // ||
  
     {return new Node(Id.BINARY, t.image); }
  }
  
  Node BinaryMulDiv () :
  {
    Token t;
  }
  {
    (t = &lt;MUL>   // *
  | 
    t = &lt;DIV>)   // /
  
     {return new Node(Id.BINARY, t.image); }
  }
  
  Node BinaryPlusMin () :
  {
    Token t;
  }
  {
    (t = &lt;PLUS>    // +
  | 
    t = &lt;MINUS>)   // -
  
     {return new Node(Id.BINARY, t.image); }
  }
  
  Node Unary() :
  {
    Token t;
  }
  { 
    t = &lt;MINUS> { return new Node(Id.UNARY, t.image); }
  | 
    t = &lt;NOT> { return new Node(Id.UNARY, t.image); }     // !
  }
  
  Node Identifier() :
  {
    Token t;
  }
  {
    t = &lt;IDENT> { return new Node(Id.IDENT, t.image); }
  }
  
  Node IntegerLiteral() :
  {
    Token t;
  }
  {
   t = &lt;INTEGER_LITERAL>
   { return new Node(Id.INTEGER_LITERAL, t.image); }
  }
  
  Node CharLiteral() :
  {
    Token t;
  }
  {
   t = &lt;CHAR_LITERAL>
  
    { return new Node(Id.CHAR_LITERAL, t.image); }
  }
  
  Node FileName() :
  {
      Token dot;
  }
  {
      (&lt;IDENT> &lt;DOT> &lt;IDENT>)
      { return new Node(Id.FILE_NAME); }
  }
  
  Node IncludeFile() :
  {
      Node include = new Node(Id.INCLUDE);
      Node name;
      Token incl;
      Token lt;
      Token gt;
  }
  {
      incl = &lt;INCLUDE>
      lt = &lt;LT>  
      name = FileName() { include.add(name); }
      gt = &lt;GT>
  
      { return include; }
  }
  </pre>
  
  <p>This is the program I'm using for my tests. </p>
  
  <pre>
  int main(void) {
    int i;
    1!=!3;
    4&&(6);
    7* 8+10;            // wrong tree
    10+8*7;             // right tree
    (11-12)+(12/16);
    17=27>28;
  }
  </pre>
  
  <p>I guess that the part that doesn't work in my grammar is the <em>OperatorExpression()</em> because when I print the syntax tree for the code above, I obtain two different branches for those line I put a comment in.
  Here the syntax tree</p>
  
  <pre>
  PROGRAM 
   FUNC 
    INT 
    IDENT ( main ) 
    VOID 
    COMPOUND_STMNT 
     VARDEC 
      INT 
      IDENT ( i ) 
     STMNT 
      BINARY ( != ) 
       INTEGER_LITERAL ( 1 ) 
      INTEGER_LITERAL ( 3 ) 
      UNARY ( ! ) 
     STMNT 
      BINARY ( && ) 
       INTEGER_LITERAL ( 4 ) 
      PAREN 
       INTEGER_LITERAL ( 6 ) 
     STMNT 
      BINARY ( * ) 
       INTEGER_LITERAL ( 7 ) 
       BINARY ( + ) 
        INTEGER_LITERAL ( 8 ) 
        INTEGER_LITERAL ( 10 ) 
     STMNT 
      BINARY ( + ) 
       INTEGER_LITERAL ( 10 ) 
       BINARY ( * ) 
        INTEGER_LITERAL ( 8 ) 
        INTEGER_LITERAL ( 7 ) 
     STMNT 
      BINARY ( + ) 
       PAREN 
        BINARY ( - ) 
         INTEGER_LITERAL ( 11 ) 
         INTEGER_LITERAL ( 12 ) 
       PAREN 
        BINARY ( / ) 
         INTEGER_LITERAL ( 12 ) 
         INTEGER_LITERAL ( 16 ) 
     STMNT 
      BINARY ( = ) 
       INTEGER_LITERAL ( 25 ) 
      BINARY ( > ) 
       INTEGER_LITERAL ( 27 ) 
      INTEGER_LITERAL ( 28 ) 
  </pre>
  
  <p>Any help is really appreciate! Thanks</p>