Пропустить подчеркивание в числах antlr4

#regex #antlr4

#регулярное выражение #antlr4

Вопрос:

Я пишу токен, который может анализировать числа с подчеркиванием, число должно начинаться с числа в [0-9].

Я сделал:

INT: [0-9] ([0-9]|(('_')->channel(HIDDEN)))*

и он не пропустит подчеркивание для меня, включая первое место, скажем, _1234 анализируется как _1234 и 123_4 также анализируется как 123_4 , что заставляет меня чувствовать себя сбитым с толку. Как может первый случай не завершиться неудачей, когда он может быть захвачен только [0-9], и как может второй случай завершиться неудачей из-за скрытия подчеркивания?

Например:

  1. Если я хочу захватить 1234_56 , мой токен должен вернуть 123456
  2. Если я хочу захватить _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('_','')}