0

私は現在、SQL ステートメントを受け入れる ANTLR 文法に取り組んでいます。この文法を使用して、プログラマーが mysql クエリを作成できるようにしたいと考えています。アプリケーションは、クエリを必要なデータベースの適切な形式に自動的に変更します。

たとえば、クエリで LIMIT 0,5 を使用すると、このクエリが mssql の適切な形式に自動的に変換されます。

これが今までの私のグラマーです

grammar sql2;

query   
    : select ';'?  EOF
    ;

select
    : 'SELECT' top? select_exp 'FROM' table ('WHERE' compare_exp)? limit?
    ;

compare_exp
    : field CompareOperator param (BooleanOperator compare_exp)?
    ;

param
    : '@' ID
    ;

top
    : 'TOP' INT
    ;

limit
    : 'LIMIT' INT (',' INT)?
    ;

select_exp
    : field (',' select_exp)?
    ;

table
    : '`' ID '`' ('.`' ID '`')?
    | ID ('.' ID)?
    ;

field
    : table
    ;

ID  :   ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;

CompareOperator
    : ( '=' | '<>' )
    ;

BooleanOperator
    : ('AND' | 'OR')
    ;

INT :   '0'..'9'+
    ;

WS  :   ( ' '
        | '\t'
        | '\r'
        | '\n'
        ) {$channel=HIDDEN;}
    ;

これを入力でテストすると

SELECT TOP 5 bla_asdf, bal, lab FROM `x`.`y` WHERE xdf = @tf AND bla = @b LIMIT 0, 5

AND bla = @bでクエリの解析を停止し、その時点でNoViableAltExceptionが発生します...入力を入れると

SELECT TOP 5 bla_asdf, bal, lab FROM `x`.`y` WHERE xdf = @tf LIMIT 0, 5

それは私に何の問題も与えません。

私は ANTLR の専門家ではありませんが、ここで何が間違っているのかわかりません。

誰でもこれについて私を助けることができますか?

乾杯

4

1 に答える 1

1

最長の入力フラグメントに一致する最初のレクサー ルールが優先されるため、AND は ID としてトークン化されます。

したがって、ID の前に BooleanOperator を定義する必要があります。

于 2012-08-07T21:16:20.303 に答える