AntLR4定义具有字符排除项但不为空字符串的解析器规则

时间:2018-10-30 12:32:49

标签: grammar antlr4

我已经定义了如下的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,以使其与至少一个不在禁止字符列表中的字符匹配,但不能为空?

1 个答案:

答案 0 :(得分:1)

我相信Antlr告诉您TERM*可以匹配空字符串,而不是TERM可以匹配。 TERM不能匹配空字符串,但是TERM*当然可以,这将在catSearch中引起问题:

catSearch : ... (OPEN_BR (catSearch | booleSearch | TERM*)+ CLOSE_BR) ;

Antlr无法处理可以匹配空字符串的模式重复,因为重复完全是模棱两可的。它可以在任意点匹配任意数量的空字符串,因此甚至无法知道要匹配多少重复。

如果更改内部重复,则:

 (catSearch | booleSearch | TERM*)+ 

 (catSearch | booleSearch | TERM)+ 

它将完全匹配相同的字符串,但毫不含糊。