Как можно использовать метасимвол отрицания ~ в правилах ANTLR lexer- и parser?
Отрицание внутри правил лексера и парсера
Ответ 1
Отрицание может происходить внутри правил lexer и parser.
Внутри правил lexer вы можете отрицать символы, а внутри правил парсера вы можете сбрасывать токены (правила lexer). Но оба правила lexer- и parser могут только отрицать либо одиночные символы, либо одиночные токены соответственно.
Несколько примеров:
правила lexer
Чтобы соответствовать одному или нескольким символам, кроме строчных букв ascii, вы можете:
NO_LOWERCASE : ~('a'..'z')+ ;
(отрицание-meta- char, ~ имеет более высокий приоритет, чем +, поэтому приведенное выше правило равно (~('a'..'z'))+)
Обратите внимание, что 'a'..'z' соответствует одному символу (и может быть отменено), но следующее правило недействительно:
ANY_EXCEPT_AB : ~('ab') ;
Потому что 'ab' (очевидно) соответствует 2 символам, его нельзя отменить. Чтобы сопоставить токен, состоящий из 2 символов, но не 'ab', вам нужно будет сделать следующее:
ANY_EXCEPT_AB
: 'a' ~'b' // any two chars starting with 'a' followed by any other than 'b'
| ~'a' . // other than 'a' followed by any char
;
правила анализатора
Внутри правил парсера ~ отменяет определенный токен или более одного токена. Например, вы определили следующие маркеры:
A : 'A';
B : 'B';
C : 'C';
D : 'D';
E : 'E';
Если вы хотите совместить любой токен, кроме A, выполните следующие действия:
p : ~A ;
И если вы хотите совместить любой токен, кроме B и D, вы можете сделать:
p : ~(B | D) ;
Однако, если вы хотите сопоставить любые два токена, кроме A, за которыми следует B, вы не можете сделать:
p : ~(A B) ;
Как и в случае с правилами lexer, вы не можете отрицать больше, чем один токен. Чтобы выполнить вышеизложенное, вам нужно сделать:
P
: A ~B
| ~A .
;
Обратите внимание, что . (DOT) char в правилах анализатора не соответствует любому символу, как и внутри правил lexer. Внутри правил парсера он соответствует любому токену (A, B, C, D или E, в этом случае).
Обратите внимание, что вы не можете отменить правила парсера. Недопустимо следующее:
p : ~a ;
a : A ;