ANTLR4: обработка пробелов
Я видел много грамматик ANTLR, которые используют обработку пробелов следующим образом:
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" не требует пробела между ними).
Есть ли простой способ сделать это?
Ответы
Ответ 1
Добавить правило IDENTIFIER
lexer для обработки слов, которые не являются ключевыми словами.
IDENTIFIER : [a-zA-Z]+;
Теперь текст nottrue
- это единственный тег IDENTIFIER
, который ваш парсер не будет принимать вместо отдельных ключевых слов в not true
.
Убедитесь, что IDENTIFIER
определяется после других ключевых слов. Лексер найдет, что оба NOT
и IDENTIFIER
соответствуют тексту NOT
, и назначат тип токена первой, которая появляется в грамматике.