2017-10-18 7 views
1

ANTLR 4を使用してOracle DBの一部のSelect文の簡単な文法を作成しようとしました。そして小さな問題に直面した。

文法&レクサーレクサールールは必要でないところで認識されます

column 
: (tableAlias '.')? IDENT ((AS)? colAlias)? 
| expression ((AS)? colAlias)? 
| caseWhenClause ((AS)? colAlias)? 
| rankAggregate ((AS)? colAlias)? 
| rankAnalytic colAlias 
; 

colAlias 
: '"' IDENT '"' 
| IDENT 
; 

rankAnalytic 
: RANK '(' ')' OVER '(' queryPartitionClause orderByClause ')' 
; 

RANK: R A N K; 
fragment A:('a'|'A'); 
fragment N:('n'|'N'); 
fragment R:('r'|'R'); 
fragment K:('k'|'K'); 

COLUMN宣言rankAnalytic一部であり、最も重要な部分:私は、次の文法を持っています。私はRankステートメントがcolAliasであるべきだと宣言しましたが、このcolAliasが "ランク"(引用符なし)のように呼び出された場合、RANKレクサールールとして認識されますが、colAliasとして認識されません。

だから、場合例えば、私は、次のテキストを持っている:

SELECT fulfillment_bundle_id, SKU, SKU_ACTIVE, PARENT_SKU, SKU_NAME, LAST_MODIFIED_DATE, 
RANK() over (PARTITION BY fulfillment_bundle_id, SKU, PARENT_SKU 
order by ACTIVE DESC NULLS LAST,SKU_NAME) rank 

「ランク」の別名は、次のエラーと間違いとして下線とマークされます。
不一致入力「ランク」期待{「"」、IDENT}
しかし、ポイントは、私はそれがRANKレクサーの単語として認識されるようにしたくないということですが、ご提案の列。
オープン:)

0の別名としてのみランク

答えて

1

IDENTルールの上に明らかに表示されるルールであるため、文字列「rank」はIDENTトークンとしてレクサーから放出されません。

colAlias 
    : '"' (IDENT | RANK) '"' 
    | (IDENT | RANK) 
    ; 

OPが追加さ:

簡単な修正がcolAliasルール変更することである

Ok but in case I have not only RANK as a lexer rule but the whole list (>100) of such key words... What am I supposed to do?

colAlias場合は、文字通り何もすることができが、それをしてみましょう:

colAlias 
    : '"' .+? '"' // must quote if multiple 
    | .    // one token 
    ; 

帽子の定義は、述語が一致を修飾するために必要な、あいまいさを被る:

colAlias 
    : '"' m+=.+? '"' { check($m) }? // multiple 
    | o=.   { check($o) }? // one 
    ; 

機能的には、述語がサブルールでちょうど別の要素です。

+0

しかし、私はレクサールールとしてのRANKだけでなく、そのようなキーワードのリスト全体(> 100)...私は何をすべきですか?あなたが上に示したようにそれらのすべてを外にリストしますか?私はそのような場合、リストが長く続くと思うし、新しいレクサーが追加されるたびに更新する必要があるだろう。 –

+0

更新された答え。 – GRosenberg

関連する問題