ANTLR4: обработка пробелов


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

WS: [ ntr]+ -> skip;
// or
WS: [ ntr]+ -> channel(HIDDEN);

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

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

grammar Not;

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

NOT:    'not';
TRUE:   'true';
FALSE:  'false';
WS: [ ntr]+ -> skip;
Допустимыми входными данными являются " не истинно " или " не ложно", но также " не истинно", что не является желаемым результатом. Изменение грамматики на:
grammar Not;

start:      expression;

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

NOT:    'not';

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

WS: [ ntr];

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

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

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

1 ответ:

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

IDENTIFIER : [a-zA-Z]+;

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

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