我正在为 SQL 的一个子集制作语法,我粘贴在下面:
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"标记之前的逗号成为节点的子节点,而它应该是 的子节点。
我的问题是幕后发生了什么导致这种情况?
显然,当您使用文字符号作为令牌并将其作为另一个令牌的一部分时,ANTLR 不喜欢它。就我而言,逗号令牌既用作文字标记,又用作BOOL_OP令牌的一部分。
未来的问题可能是,当相同的符号用作仅适用于特定范围的不同令牌的一部分时,ANTLR如何消除歧义。但是,这个问题现在得到了解答。