How to parse a VB Case expression?

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)?                 #caseFromTo
    | (IS whiteSpace comparisonOperator whiteSpace)? expression         #caseIs
;

CaseFromToContext CaseIsContext ( ), ~ 1000 .

: ", !" :

rangeClause :
      expression whiteSpace TO whiteSpace expression                    #caseFromTo
    | IS whiteSpace comparisonOperator whiteSpace expression            #caseIs
    | expression                                                        #caseExpr
;

... , .

rangeClause Case Is = foobar? ANTLR 4.3, ANTLR 4.6 .

, VBAParser.g4 github.

+4
1

, , , , IS whiteSpace comparisonOperator :

rangeClause :
    (IS whiteSpace?)? comparisonOperator whiteSpace? expression
    | selectStartValue whiteSpace TO whiteSpace selectEndValue 
    | expression

expression ( selectStartValue selectEndValue), Is =, comparisonOperator comparisonOperator . , , comparisonOperator comparisonOperator expression ( VBA AFAIK), .

, , "" comparisonOperator comparisonOperator rangeClause, expression.

+1

Source: https://habr.com/ru/post/1666533/


All Articles