grammar TestGrammar;
AND : 'AND' ;
OR : 'OR'|',' ;
NOT : 'NOT' ;
LPAREN : '(' ;
RPAREN : ')' ;
DQUOTE : '"' ;
WORD : [a-z0-9._#+=]+(' '[a-z0-9._#+=]+)* ;
WS : [ \t\r\n]+ -> skip ;
quotedword : DQUOTE WORD DQUOTE;
expression
: LPAREN expression+ RPAREN
| expression (AND expression)+
| expression (OR expression)+
| expression (NOT expression)+
| NOT expression+
| quotedword
| WORD;
我设法为antlr4实现上述语法。
我还有很长的路要走但是现在我的问题是,
如何使WORD
通用?基本上我希望此[a-z0-9._#+=]
除了运算符之外的任何内容(AND
,OR
,NOT
,LPAREN
,RPAREN
,{{1} },DQUOTE
)。
答案 0 :(得分:1)
词法分析器将使用可以匹配给定输入的第一个规则。只有当该规则不匹配时,它才会尝试下一个规则。
因此,您可以使用此语法使WORD
规则具有通用性:
AND : 'AND' ;
OR : 'OR'|',' ;
NOT : 'NOT' ;
LPAREN : '(' ;
RPAREN : ')' ;
DQUOTE : '"' ;
WS : [ \t\r\n]+ -> skip ;
WORD: .+? ;
确保在这种情况下使用非贪婪的运算符?
,否则一旦被调用,WORD
规则将消耗所有后续输入。
如最后指定WORD
,如果所有先前的词法分析器规则(以上在源代码中已定义的所有规则)都失败,则仅尝试使用输入。
编辑:如果您不希望WORD
规则与任何输入匹配,那么您只需修改我提供的规则即可。但我的回答的本质是,在词法分析器中,只要您在源代码中获得了正确的顺序,就不必担心两个可能匹配相同输入的规则。
答案 1 :(得分:1)
尝试类似这样的语法:
select s.Dim, s.Frequency, s.Date, max(s.Version)
from sample_tbl s
inner (
SELECT Dim, Frequency, max(Date) as max_date
FROM sample_tbl
group by Dim, Frequency
) t on t.Dim = s.Dim, t.Frequency = s.Frequency t.max_date = s.Date
GROUP BY s.Dim, s.Frequency, s.Date ;
也许您想在grammar TestGrammar;
...
WORD : Letter+;
QUOTEDWORD : '"' (~["\\\r\n])* '"' // disallow quotes, backslashes and crlf in literals
WS : [ \t\r\n]+ -> skip ;
fragment Letter :
[a-zA-Z$_] // these are the "java letters" below 0x7F
| ~[\u0000-\u007F\uD800-\uDBFF] // covers all characters above 0x7F which are not a surrogate
| [\uD800-\uDBFF] [\uDC00-\uDFFF] // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
;
expression:
...
| QUOTEDWORD
| WORD+;
中使用转义序列,然后查看this example如何执行此操作。
这个语法允许你: