Vladimir Kozhaev
Vladimir Kozhaev

Reputation: 21

Can't parse an existing expression with the antlr4 grammar(see it in the question)

I have the following grammar

grammar ExpressionsParserGrammar;

expression
:
    left = expression identity_operation =
    (
        IDENTITY
        | NOT_IDENTITY
    ) right = expression # identity_operation
    | left = expression equality_operation =
    (
        EQUALS
        | NOT_EQUALS
        | MORE_THAN
        | LESS
        | MORE_OR_EQUALS
        | LESS_OR_EQUALS
    ) right = expression # equality_operation
    | condition = expression '?' left = expression COLON right = expression #
    question_expr
    | left = expression mul_or_div =
    (
        MUL
        | DIV
    ) right = expression # mul_div_expr
    | left = expression plus_minus =
    (
        PLUS
        | MINUS
    ) right = expression # add_expr
    | NOT expr = expression # not_expr
    | left = expression AND right = expression # and_expr
    | left = expression OR right = expression # or_expr
    | LPAREN expr = expression RPAREN # brackets_expr
    | POWER_FUNC LPAREN expr1 = expression COMMA expr2 = expression RPAREN #
    power_expr
    | LAST_VAL_FUNC LPAREN last_str_func = STRING_VALUE
    (
        (
            COMMA config = STRING_VALUE
        )?
    ) RPAREN # last_val_func
    | LAST_STR_FUNC LPAREN last_str_func = STRING_VALUE RPAREN # last_str_func
    | SUBMISSION_VAL_FUNC LPAREN sumission_val_str = STRING_VALUE RPAREN #
    submission_val_func
    | SUBMISSION_STR_FUNC LPAREN submission_str = STRING_VALUE RPAREN #
    submission_str_func
    | DATE_FORMAT_FUNC LPAREN date_format_expr = expression COMMA formatParam =
    STRING_VALUE RPAREN # date_format_func
    | NEW DATE LPAREN
    (
        (
            expr = expression
            (
                COMMA expr = expression
            )*
        )
    )* RPAREN # date
    | DIFFERENCE_IN_HOURS LPAREN left = expression COMMA right = expression #
    dif_in_hours
    | DIFFERENCE_IN_DAYS LPAREN left = expression COMMA right = expression #
    dif_in_days
    | DIFFERENCE_IN_MINUTES LPAREN left = expression COMMA right = expression #
    dif_in_minutes
    | DATE_ADD LPAREN date = expression COMMA d=duration RPAREN  # dateAddFunc
    | DATE_SUBTRACT LPAREN date = expression COMMA d=duration RPAREN  # dateSubtractFunc
    | NOW LPAREN RPAREN # now
    | numLiteral = NUMBER_LITERAL # process_number
    | strValueLiteral = STRING_VALUE # process_str
    | boolLiteral =
    (
        TRUE
        | FALSE
    ) # process_bool
;

duration:L_CURLY_BRACE (YEARS COLON years =
    expression) ( COMMA MONTHS COLON months = expression)? (COMMA WEEKS COLON weeks =
    expression )? (COMMA DAYS COLON days = expression )? ( COMMA HOURS COLON hours = expression )?
    ( COMMA MINUTES COLON minutes = expression )? (COMMA SECONDS COLON seconds = expression)? R_CURLY_BRACE;
    
SECONDS: 'seconds';

MINUTES: 'minutes' ;


HOURS
:'hours'
;

DAYS
:
    'days'
;

WEEKS
:
    'weeks'
;

MONTHS
:
    'months'
;

YEARS
:
    'years'
;

OR
:
    '||'
;


AND
:
    '&&'
;

NOT
:
    '!'
;

DIFFERENCE_IN_MINUTES
:
    'differenceInMinutes'
;

DIFFERENCE_IN_DAYS
:
    'differenceInDays'
;

DIFFERENCE_IN_HOURS
:
    'differenceInHours'
;

DATE_ADD
:
    'dateAdd'
;

DATE_SUBTRACT
:
    'dateSubtract'
;


// ----------------- lexer -----------------
// using the NA pattern marks this Token class as 'irrelevant' for the Lexer.
// AdditionOperator defines a Tokens hierarchy but only the leafs in this hierarchy define
// actual Tokens that can appear in the text

COLON
:
    ':'
;

NOW
:
    'now'
;

NEW
:
    'new'
;

DATE
:
    'Date'
;

PLUS
:
    '+'
;

MINUS
:
    '-'
;

MUL
:
    '*'
;

DIV
:
    '/'
;

LPAREN
:
    '('
;

RPAREN
:
    ')'
;

NUMBER_LITERAL
:
    '0'
    |
    (
        [1-9]
        (
            [0-9]*
        )
    )
;

IDENTITY
:
    '==='
;

NOT_IDENTITY
:
    '!=='
;

EQUALS
:
    '=='
;

NOT_EQUALS
:
    '!='
;

MORE_THAN
:
    '>'
;

LESS
:
    '<'
;

MORE_OR_EQUALS
:
    '>='
;

LESS_OR_EQUALS
:
    '<='
;

LAST_VAL_FUNC
:
    'lastVal'
;

LAST_STR_FUNC
:
    'lastStr'
;

SUBMISSION_VAL_FUNC
:
    'submissionVal'
;

SUBMISSION_STR_FUNC
:
    'submissionStr'
;

POWER_FUNC
:
    'power'
;

DATE_FORMAT_FUNC
:
    'dateFormat'
;

COMMA
:
    ','
;

L_CURLY_BRACE
:
    '{'
;

R_CURLY_BRACE
:
    '}'
;

TRUE
:
    'true'
;

FALSE
:
    'false'
;

STRING_VALUE
:
    '"'
    (
        '\\"'
        | .
    )*? '"'
;

WS
:
    [ \r\t\n]+ -> skip
;

And on the expression

differenceInDays(new Date(1999, 10,1), true ? new Date(1999, 10,2) : "A")>3

I have following error

ExpressionsParserGrammar::expression:1:72: extraneous input ')' expecting {, '?', '||', '&&', '+', '-', '*', '/', '===', '!==', '==', '!=', '>', '<', '>=', '<='}

There is a Eclipse view of the syntax tree of my expression

enter image description here

Where I'm wrong and how to fix my grammar to make the mentioned expression fit to the grammar?

Upvotes: 2

Views: 147

Answers (1)

Bart Kiers
Bart Kiers

Reputation: 170158

The error message "extraneous input ')' expecting {, '?', '||', '&&', '+', '-', '*', '/', '===', '!==', '==', '!=', '>', '<', '>=', '<='}" is telling you that a ) is encountered, but is unexpected. The parser is trying to continue matching an expression, which might continue if one of the tokens {, '?', '||', '&&', '+', '-', '*', '/', '===', '!==', '==', '!=', '>', '<', '>=', '<='} was found instead of ).

The root cause is that in your #dif_in_days alternative, there is no RPAREN token defined:

Instead of:

| DIFFERENCE_IN_DAYS LPAREN left = expression COMMA right = expression #dif_in_days

do this:

| DIFFERENCE_IN_DAYS LPAREN left = expression COMMA right = expression RPAREN #dif_in_days

Note that the same goes for the alternatives #dif_in_hours and #dif_in_minutes: those too are missing an RPAREN token.

Upvotes: 1

Related Questions