Отрицание внутри правил лексера и парсера - PullRequest
16 голосов
/ 27 ноября 2011

Как можно использовать метасимвол отрицания, ~, в правилах лексера и синтаксического анализа ANTLR?

1 Ответ

29 голосов
/ 27 ноября 2011

Отрицание может происходить внутри правил лексера и парсера .

Внутри правил лексера вы можете отрицать символы, а внутри правил парсера вы можете отрицать токены (правила лексера). Но и правила лексера, и правила синтаксического анализатора могут отменять только одиночные символы или одиночные токены соответственно.

Пара примеров:

Правила лексера

Чтобы соответствовать одному или нескольким символам, кроме строчных букв 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) ;

Как и в случае с правилами лексеров, вы не можете отменить более одного токена. Для этого вам необходимо:

P
  :  A ~B
  |  ~A .
  ; 

Обратите внимание, что символ . (DOT) в правилах синтаксического анализа не соответствует любому символу, как в правилах лексера. В правилах синтаксического анализа он соответствует любому токену (A, B, C, D или E, в данном случае).

Обратите внимание, что вы не можете отрицать правила парсера. Следующее незаконно:

p : ~a ;
a : A  ;
...