Search code examples
javaantlr

How do I detect illegal expressions in antlr?


I use antlr JavaParser.

expression
    : primary
    | expression bop='.'
      (
         identifier
       | methodCall
       | THIS
       | NEW nonWildcardTypeArguments? innerCreator
       | SUPER superSuffix
       | explicitGenericInvocation
      )
    | expression '[' expression ']'
    | methodCall
    | NEW creator
    | '(' annotation* typeType ('&' typeType)* ')' expression
    | expression postfix=('++' | '--')
    | prefix=('+'|'-'|'++'|'--') expression
    | prefix=('~'|'!') expression
    | expression bop=('*'|'/'|'%') expression
    | expression bop=('+'|'-') expression
    | expression ('<' '<' | '>' '>' '>' | '>' '>') expression
    | expression bop=('<=' | '>=' | '>' | '<') expression
    | expression bop=INSTANCEOF (typeType | pattern)
    | expression bop=('==' | '!=') expression
    | expression bop='&' expression
    | expression bop='^' expression
    | expression bop='|' expression
    | expression bop='&&' expression
    | expression bop='||' expression
    | <assoc=right> expression bop='?' expression ':' expression
    | <assoc=right> expression
      bop=('=' | '+=' | '-=' | '*=' | '/=' | '&=' | '|=' | '^=' | '>>=' | '>>>=' | '<<=' | '%=')
      expression

But some illegal expressions cannot be detected directly.

Such as 3 > 3 ? 3 : 45 : 45, 2 > 3 > 4.

enter image description here

I wonder how the java syntax detects such illegal expressions, it's extra coding work, or the ability to use antlr itself.

If it's extra coding work, how to do it?


Solution

  • Note that from 3 > 3 ? 3 : 45 : 45 only 3 > 3 ? 3 : 45 is recognized as the expression (which is correct). If you'd test the parser with the extra rule:

    single_expression
     : expression EOF
     ;
    

    then the input 3 > 3 ? 3 : 45 : 45 will not be valid.

    As for 2 > 3 > 4: it is syntactically correct. To validate if it is semantically correct (which is not the work for a parser!), you'll need to implement type checking yourself. ANTLR's listener- and visitor classes can help, but the bulk of the work will have to be done by yourself. Also see How to implement type checking in a Listener