#regex #antlr4
#регулярное выражение #antlr4
Вопрос:
Я пишу токен, который может анализировать числа с подчеркиванием, число должно начинаться с числа в [0-9].
Я сделал:
INT: [0-9] ([0-9]|(('_')->channel(HIDDEN)))*
и он не пропустит подчеркивание для меня, включая первое место, скажем, _1234
анализируется как _1234
и 123_4
также анализируется как 123_4
, что заставляет меня чувствовать себя сбитым с толку. Как может первый случай не завершиться неудачей, когда он может быть захвачен только [0-9], и как может второй случай завершиться неудачей из-за скрытия подчеркивания?
Например:
- Если я хочу захватить
1234_56
, мой токен должен вернуть123456
- Если я хочу захватить
_1234
, мой токен должен вернуть1234
Комментарии:
1. можете ли вы привести примеры строк, которые должны и не должны совпадать? Вы просто пытаетесь захватить числовую часть ввода? Для чего предназначена часть «-> канал (СКРЫТЫЙ))»?
2. @mangotang Да, я могу
Ответ №1:
Это правило
INT: [0-9] ([0-9]|(('_')->channel(HIDDEN)))* ;
сгенерирует lexer command placement
ошибку из-за расположения -> channel
команды. Ошибка генерации означает, что сгенерированный лексер / синтаксический анализатор не следует считать допустимым. Операция может быть от тонкой до совершенно непредсказуемой.
Чтобы быть действительной, команда должна существовать на правом краю правила лексера. Его нельзя просто встроить в правило.
Лучшая рекомендация — использовать лексер для приема только допустимого входного текста (т. Е. Не Пытаться переписать входной текст в какую-либо другую форму).
INT: [0-9] ([0-9]|'_')* ;
При выполнении возможных операций вывода — действий с правилами синтаксического анализатора или обхода дерева — INT
значения токенов могут быть преобразованы в желаемую форму вывода.
Комментарии:
1. Вы можете упростить
([0-9]|'_')*
до[0-9_]*
2. @LucasTrzesniewski Поскольку у меня уже есть [0-9] для записи первых цифр, его можно упростить до
INT: [0-9][0-9_]*
.
Ответ №2:
Вы можете попробовать это с помощью python
пример:
INTLIT: ( OCT | HEX | BIN | DEC ) {self.text = self.text.replace('_','')}