2013-03-19 12 views
12

Widziałem wiele gramatyk antlr używające białymi obsługę tak:ANTLR4: Biała spacja obsługa

WS: [ \n\t\r]+ -> skip; 
// or 
WS: [ \n\t\r]+ -> channel(HIDDEN); 

Więc odstępy są wyrzucane odpowiednio wysłać do ukrytego kanału.

Z gramatyki tak:

grammar Not; 

start:  expression; 
expression: NOT expression 
      | (TRUE | FALSE); 

NOT: 'not'; 
TRUE: 'true'; 
FALSE: 'false'; 
WS: [ \n\t\r]+ -> skip; 

ważne wejścia są „nieprawda” lub „fałsznie”, ale również „nottrue”, który nie jest pożądany rezultat. Zmiana gramatyki do:

grammar Not; 

start:  expression; 

expression: NOT WS+ expression 
      | (TRUE | FALSE); 

NOT: 'not'; 

TRUE: 'true'; 
FALSE: 'false'; 

WS: [ \n\t\r]; 

rozwiązuje problem, ale nie chcę, aby ręcznie obsługiwać spacje w każdej reguły.

Generalnie chcę mieć spacje między każdym tokenem z pewnymi wyjątkami (np. "! True" nie wymaga odstępu).

Czy istnieje prosty sposób na zrobienie tego?

Odpowiedz

11

Dodaj regułę leksykalną IDENTIFIER do obsługi słów niebędących słowami kluczowymi.

IDENTIFIER : [a-zA-Z]+; 

Teraz tekst nottrue jest pojedynczym IDENTIFIER żeton, który swoją parser nie zaakceptuje w miejsce odrębnych słów kluczowych w not true.

Upewnij się, że IDENTIFIER jest zdefiniowany po innych Twoich słów kluczowych. Lexer znajdzie, że zarówno NOT, jak i IDENTIFIER pasuje do tekstu not i przypisze typ tokena do pierwszego, który pojawi się w gramatyce.

+0

Dzięki. Działa to zgodnie z życzeniem dla "* nottrue *" (nieprawidłowy) i "*! True *" (prawidłowy). Czy masz również pomysł, w jaki sposób mogę zrobić wyjątek od tej reguły, aby możliwe było pominięcie białych znaków w innych danych wejściowych? Podobnie jak "* A B true *", gdzie spacje między literami A i B są opcjonalne. Jest to również poprawne: "* AB true *", ale "* ABtrue *" nie. – flux