AntLR4 определяет правило парсера с символьными исключениями, но не пустой строкой - PullRequest
0 голосов
/ 30 октября 2018

Я определил грамматику 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 голосов
/ 01 ноября 2018

Я считаю, что Antlr говорит вам, что TERM* может соответствовать пустой строке, а не TERM. TERM не может соответствовать пустой строке, но, конечно, TERM* может, и это вызовет проблему в catSearch:

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

Antlr не может обрабатывать повторения шаблонов, которые могут соответствовать пустой строке, потому что повторение является совершенно неоднозначным. Он может соответствовать произвольному количеству пустых строк в любом указателе, поэтому нет способа узнать даже, сколько повторений должно быть сопоставлено.

Если вы измените внутреннее повторение:

 (catSearch | booleSearch | TERM*)+ 

до

 (catSearch | booleSearch | TERM)+ 

Он будет соответствовать точно таким же строкам, но однозначно.

...