Search code examples
javacc

right associative operator in javacc


I need to write a program that checks types for F1 type system and I don't know how to make rules that makes right associative operator.

What I need is that if I parse something like Nat -> Nat -> Nat, that should be parsed as Nat -> (Nat -> Nat), not as (Nat -> Nat) -> Nat (I want to build an AST and do stuff on that)

what I have now is:

Node Type2() {Node t1;}
{
    "Nat" { return Node("Nat", null, null);}
    |
    "Bool" { return Node("Bool", null, null);}
    |
    "(" t1=Type() ")" {return t1;}
}
Node Type() {Node t1; Node t2;}
{
    t1 = Type2() (" -> " t2 = Type2() { return Node("->", t1, t2); }
}

but it is left associative, how can I make this right?

the grammar is:

type              = "Bool" | "Nat" | type, "->", type | "(", type, ")";
lambda_expression = variable
              | "\", variable, ":", type, ".", lambda_expression
              | lambda_expression, " ", lambda_expression
              | "(", lambda_expression, ")";
type_context      = variable, ":", type, { ",", variable, ":", type };
expression        = [ type_context ], "|-", lambda_expression, ":", type;

thanks


Solution

  • Use a loop in place of recursion

    Node Type() :
    {Node t1; Node t2;}
    {
        t1 = Type2()
        (   " -> "
            t2 = Type2() 
            { t1 =  Node("->", t1, t2); }
        )*
        {return t1 ; }
    }
    

    Or --what amounts to the same thing-- use right recursion.

    Node Type() :
    {Node t1;}
    {
        t1 = Type2()
        t1 = MoreType( t1 ) ;
        {return t1 ; }
    }
    
    Node MoreType(Node t1) :
    {Node t2;}
    {
        " -> " t2 = Type2() t1 = MoreType( new Node( "->", t1, t2 ) ) {return t1; }
    |
        {return t1; }
    }