2017-01-11 5 views
4

私はVBAコードを解析しようとしている、とスペックの5.4.2.10節では、次のように我々が定義したSelect Case文を定義しますVB Caseステートメントを正しく解析する方法は?

// 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; 

問題がrangeClauseexpressionを取っているということです

Select Case foo 
    Case Is = 42 
     Exit Sub 
End Select 

が...最終的に取り上げ、問題がある{undeclared-variable} {EQ} {literal}、として扱われます 、理由:優先順位は、このなりますは、レクサーのトークンではなく、比較式のLHSであるべきだ:

expression whiteSpace? (EQ | NEQ | LT | GT | LEQ | GEQ | LIKE | IS) whiteSpace? expression # relationalOp 

私はexpressionブランチは、このような優先順位が低い、となるように選択肢を並べ替えてみました:

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 
; 

そしてコード内のCaseFromToContextCaseIsContextクラス(コンパイルしたままにしておく必要がありました)を使用していましたが、私のプロジェクトで1000テストを壊しました。

それから、私は "ちょっと曖昧ですね"と考えました。

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

...ただし運がなく、同じ結果です。

をこの厄介な意味を理解できるようにするにはCase Is = foobar構文を使用しますか?私はANTLR 4.3を使用していますが、ANTLR 4.6にすぐにアップグレードする予定です。

追加のコンテキストが必要な場合はthe complete VBAParser.g4 grammar is on githubです。

答えて

1

は再発注が実際に作業を行うことが判明したが、解析のうち、あいまいさを保つために、IS whiteSpace comparisonOperatorが最初に来ています

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

問題がexpressionで(ひいてはですselectStartValueそしてselectEndValue)であり、これはと再帰的に一致する。なぜなら、comparisonOperator comparisonOperatorは表現一致であるからである。 に行うことができる仕事はおそらくcomparisonOperator comparisonOperatorexpression(これはVBA AFAIKでは有効ではありません)との一致を避けていますが、上記はすばやく不潔な修正として機能します。

基本的には上記のすべての文法はありませんが、それはexpressionと一致させることができる前rangeClauseとして「無効」comparisonOperator comparisonOperator一致していることを確認しています。

関連する問題