Search code examples
antlr4greedy

ANTLR matches addition over lambda body


I have a simple ANTLR grammar with arithmetic, boolean and lambda expressions. It incorrectly parses fun x -> x + 1 as (fun x -> x) + 1 rather than fun x -> (x +1) even though the lambda rule is on top of the addition rule.

expression
    : number                                                              # NumberExpr
    | bool                                                                # BooleanExpr
    | 'fun' args=ID+ '->' body=expression                                 # LambdaExpr
    | callee=expression args=expression+                                  # CallExpr
    | 'let' name=ID '=' value=expression 'in' body=expression             # LetExpr
    | name=ID                                                             # VarExpr
    | 'if' test=expression 'then' then=expression 'else' else_=expression # IfThenElseExpr
    | '(' inner=expression ')'                                            # ParensExpr
    | left=expression operator=MUL right=expression                       # MultiplicationExpr
    | left=expression operator=DIV right=expression                       # DivisionExpr
    | left=expression operator=ADD right=expression                       # AdditionExpr
    | left=expression operator=SUB right=expression                       # SubtractionExpr
    | left=expression operator=AND right=expression                       # AndExpr
    | left=expression operator=OR  right=expression                       # OrExpr
    | left=expression operator=EQ right=expression                        # EqExpr

Solution

  • Not though, but because.

    The expression a * b + c is parsed as (a * b) + c and expression a + b * c as a + (b * c) because multiplication has higher priority.

    In your case, lambda has priority over addition so that's nothing wrong that fun x -> x + 1 was parsed as (fun x -> x) + 1 because a higher-priority operation must be done first and lower-priority second.

    Just move the lambda rule under the addition rule to fix it.