2016-05-22 5 views
0

私は以下の貼り付けましたSQLのサブセットのための文法を作ってるんだ:ANTLR 4建物の解析ツリーが誤っ

grammar Sql; 

sel_stmt : SEL QUANT? col_list FROM tab_list; 
as_stmt : 'as' ID; 
col_list : '*' | col_spec (',' col_spec | ',' col_group)*; 
    col_spec : (ID | ID '.' ID) as_stmt?; 
    col_group : ID '.' '*'; 
tab_list : (tab_spec | join_tab) (',' tab_spec | ',' join_tab)*; 
tab_spec : (ID | sub_query) as_stmt?; 
sub_query : '(' sel_stmt ')'; 

join_tab : tab_spec (join_type? 'join' tab_spec 'on' cond_list)+; 
    join_type : 'inner' | 'full' | 'left' | 'right'; 
cond_list : cond_term (BOOL_OP cond_term)*; 
cond_term : col_spec (COMP_OP val | between | like); 
    val : INT | FLT | SQ_STR | DQ_STR; 
    between : ('not')? 'between' val 'and' val; 
    like : ('not')? 'like' (SQ_STR | DQ_STR); 

WS : (' ' | '\t' | '\n')+ -> skip; 
INT : ('0'..'9')+; 
FLT : INT '.' INT; 
SQ_STR : '\'' ~('\\'|'\'')* '\''; 
DQ_STR : '"' ~('\\'|'"')* '"'; 
BOOL_OP : ',' | 'or' | 'and'; 
COMP_OP : '=' | '<>' | '<' | '>' | '<=' | '>='; 

SEL : 'select' | 'SELECT'; 
QUANT: 'distinct' | 'DISTINCT' | 'all' | 'ALL'; 
FROM: 'from' | 'FROM'; 
ID : ('A'..'Z' | 'a'..'z')('A'..'Z' | 'a'..'z' | '0'..'9')*; 

入力私はテストがselect distinct test.col1 as col, test2.* from test join test2 on col='something', test2.col1=1.4ですよ。出力構文解析ツリーは、test2の最後の出現をaと一致させ、入力の残りの部分をどのように処理するかを知りません。最後の 'test2'トークンの前のコンマは、ノードの子でなければなりません。

私の質問は、これを引き起こすために舞台裏で行われていることですか?

+0

ちなみに、この例の最後の部分は、有効なANSI SQLであるとは思われません。 –

答えて

0

明らかにANTLRは、リテラルシンボルをトークンとして使用し、それを別のトークンの一部にすると、ANTLRが好きではありません。私の場合、カンマトークンはリテラルトークンとBOOL_OPトークンの一部として使用されていました。

今後、特定のスコープでのみ適用される異なるトークンの一部として同じシンボルが使用された場合、ANTLRがどのように曖昧さを解消するのかについて、今後の質問があります。しかし、この質問は今のところ答えられています。

+0

これは、ANTLRのあいまいなレクサールールを使用するのは非常に古典的な間違いです。 ANTLRがどのように曖昧さを解消するのかを知る必要があります(暗黙のトークンタイプ、文法の順)。私は何度も同じような質問に答えてきましたが、あなたの問題に似ています[ここ](http://stackoverflow.com/a/36619004/3764814)を見てください。 –