I am trying to parse VBA code, and section 5.4.2.10 of the specification defines an operator Select Case, which we defined as follows:
// 5.4.2.10 Select Case Statement
selectCaseStmt :
SELECT whiteSpace? CASE whiteSpace? selectExpression endOfStatement
caseClause*
caseElseClause?
END_SELECT
;
selectExpression : expression;
caseClause :
CASE whiteSpace rangeClause (whiteSpace? COMMA whiteSpace? rangeClause)* endOfStatement block
;
caseElseClause : CASE whiteSpace? ELSE endOfStatement block;
rangeClause :
expression
| selectStartValue whiteSpace TO whiteSpace selectEndValue
| (IS whiteSpace?)? comparisonOperator whiteSpace? expression
;
selectStartValue : expression;
selectEndValue : expression;
The problem is that expressionin rangeClausetakes precedence and does the following:
Select Case foo
Case Is = 42
Exit Sub
End Select
... ultimately get and process as {undeclared-variable} {EQ} {literal}, which is a problem, because it Ismust be the token of the lexer, not the LHS comparison expression:
expression whiteSpace? (EQ | NEQ | LT | GT | LEQ | GEQ | LIKE | IS) whiteSpace? expression # relationalOp
I tried reordering the alternatives so that the branch expressionhas a lower priority, for example:
rangeClause :
selectStartValue whiteSpace TO whiteSpace selectEndValue
| (IS whiteSpace?)? comparisonOperator whiteSpace? expression
| expression
;
( ~ 1000 ), rangeClause ( , Is = VBA):
rangeClause :
expression (whiteSpace TO whiteSpace expression)?
| (IS whiteSpace comparisonOperator whiteSpace)? expression
;
CaseFromToContext CaseIsContext ( ), ~ 1000 .
: ", !" :
rangeClause :
expression whiteSpace TO whiteSpace expression
| IS whiteSpace comparisonOperator whiteSpace expression
| expression
;
... , .
rangeClause Case Is = foobar? ANTLR 4.3, ANTLR 4.6 .
, VBAParser.g4 github.