2013-03-19 3 views
12

Я видел много грамматик Antlr, которые используют пробельные обработку, как это:ANTLR4: Пробелы обработка

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

Так пробельные символы отбрасываются соответственно отправить на скрытый канал.

С грамматикой, как это:

grammar Not; 

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

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

действительные входы «не так» или «не ложно», но и «nottrue», который не является желаемым результатом. Изменение грамматика:

grammar Not; 

start:  expression; 

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

NOT: 'not'; 

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

WS: [ \n\t\r]; 

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

Обычно я хочу иметь пробел между каждым токеном с некоторыми исключениями (например, «! True» не требуется пробел между ними).

Есть ли простой способ сделать это?

ответ

11

Добавить правило IDENTIFIER lexer для обработки слов, которые не являются ключевыми словами.

IDENTIFIER : [a-zA-Z]+; 

Теперь текст nottrue является единственным IDENTIFIER маркер, который парсер не будет принимать вместо отдельных ключевых слов в not true.

Удостоверяются, что IDENTIFIER определено после ваших других ключевых слов. Лексер найдет, что и NOT, и IDENTIFIER соответствуют тексту not, и назначат тип токена первой, которая появляется в грамматике.

+0

Спасибо. Это работает по желанию для '* nottrue *' (недействительно) и '*! True *' (действительный). У вас также есть идея, как я могу сделать исключение из этого правила, чтобы некоторые другие входы могли пропускать пробелы? Подобно '* A B true *', где пробелы между A и B являются необязательными. Так что это также верно: '* AB true *', но '* ABtrue *' нет. – flux

 Смежные вопросы

  • Нет связанных вопросов^_^