ANTLR4 grammar for String, Boolean, and Numeric expressions that are not mutually left-recursive

45 views Asked by At

I'm trying to create a grammar for expression evaluation that differentiates between String, Boolean, and Numeric expressions.

Here's the relevant grammar so far:

functionInvocation: IDENTIFIER '(' ( IDENTIFIER '=' expression ( ',' IDENTIFIER '=' expression )* )? ')' ;

expression
    : stringExpression 
    | booleanExpression 
    | numericExpression
    ;

stringExpression
    : '(' stringExpression ')'
    | stringExpression '+' stringExpression
    | <assoc=right> booleanExpression '?' stringExpression ':' stringExpression 
    | STRING_LITERAL
    | IDENTIFIER
    | functionInvocation
    ;

booleanExpression
    : '(' booleanExpression ')'
    | NOT booleanExpression
    | booleanExpression LOGICAL_AND booleanExpression
    | booleanExpression LOGICAL_OR booleanExpression
    | numericExpression ( LESS_THAN | LESS_THAN_OR_EQUAL_TO | GREATER_THAN | GREATER_THAN_OR_EQUAL_TO ) numericExpression
    | stringExpression ( LESS_THAN | LESS_THAN_OR_EQUAL_TO | GREATER_THAN | GREATER_THAN_OR_EQUAL_TO ) stringExpression
    | numericExpression ( IS_EQUAL_TO | NOT_EQUAL_TO ) numericExpression
    | stringExpression ( IS_EQUAL_TO | NOT_EQUAL_TO ) stringExpression
    | <assoc=right> booleanExpression '?' booleanExpression ':' booleanExpression
    | stringExpression '=~' 'm/' REGEX_PATTERN '/' REGEX_OPTIONS
    | BOOLEAN_TRUE
    | BOOLEAN_FALSE
    | IDENTIFIER
    | functionInvocation 
    ;

numericExpression 
    : '(' numericExpression ')' #mathSubExpression
    | ( PLUS | MINUS | NOT )? mathAtom #unaryOperation
    | numericExpression POWER numericExpression #binaryOperation
    | numericExpression ( MULTIPLY | DIVIDE | MODULO ) numericExpression #binaryOperation
    | numericExpression ( ADD | SUBTRACT ) numericExpression #binaryOperation
    | numericExpression ( SHIFT_LEFT | SHIFT_RIGHT ) numericExpression #binaryOperation
    | numericExpression BITWISE_AND numericExpression #binaryOperation
    | numericExpression BITWISE_XOR numericExpression #binaryOperation
    | numericExpression BITWISE_OR numericExpression #binaryOperation
    ;
mathAtom
    : BINARY_LITERAL
    | FLOAT_LITERAL
    | HEX_LITERAL
    | INTEGER_LITERAL
    | OCTAL_LITERAL
    | SCIENTIFIC_NOTATION_LITERAL
    | IDENTIFIER
    | functionInvocation
    ;

I'm ending up with stringExpression and booleanExpression being mutually left-recursive because of the ternary operator in stringExpression.

Is there a way of expressing the intent that is not mutually left-recursive?

0

There are 0 answers