我已经定义了如下的AntLR4语法:
catSearch : (NOT? CATEGORY expr)+ | (OPEN_BR (catSearch | booleSearch | TERM*)+ CLOSE_BR) ;
expr : (NOT? searchValue)+ | BETWEEN;
searchValue : (TERM | PHRASE | NULL | NOT_NULL ) ;
CATEGORY : ([Aa][Dd] | [Xx][Ii])'=';
// Brackets
OPEN_BR: '(' ;
CLOSE_BR: ')' ;
// boolean operators
AND : ([Aa][Nn][Dd]) ;
OR : ([Oo][Rr]) ;
NOT : ([Nn][Oo][Tt]) ;
NULL: 'NULL' ;
NOT_NULL: 'NNULL' ;
BETWEEN: TERM'^'TERM ;
// match single search term
TERM : ~['('')''='' ''^']+ ;
// any double quoted string
PHRASE : '"' .*? '"' ;
// skip spaces, tabs, newlines
WS : [ \t\r\n]+ -> skip ;
在catSearch AntLR规则中,错误提示TERM可以匹配空字符串。如何定义TERM,以使其与至少一个不在禁止字符列表中的字符匹配,但不能为空?
答案 0 :(得分:1)
我相信Antlr告诉您TERM*
可以匹配空字符串,而不是TERM
可以匹配。 TERM
不能匹配空字符串,但是TERM*
当然可以,这将在catSearch
中引起问题:
catSearch : ... (OPEN_BR (catSearch | booleSearch | TERM*)+ CLOSE_BR) ;
Antlr无法处理可以匹配空字符串的模式重复,因为重复完全是模棱两可的。它可以在任意点匹配任意数量的空字符串,因此甚至无法知道要匹配多少重复。
如果更改内部重复,则:
(catSearch | booleSearch | TERM*)+
到
(catSearch | booleSearch | TERM)+
它将完全匹配相同的字符串,但毫不含糊。