Обратите внимание, что ваше правило может быть переписано в:
ID
: ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '0'..'9' |'_')*
;
или с fragments
(правила, которые не производят токены, но используются только другими правилами лексера):
ID
: (Letter | '_') (Letter| Digit |'_')*
;
fragment Letter
: 'a'..'z'
| 'A'..'Z'
;
fragment Digit
: '0'..'9'
;
Но если ввод, такой как "3a"
, распознается вашим лексером и выдает токены INT
и ID
, то вам не следует ничего менять.Проблема с таким вводом, вероятно, возникнет в ваших правилах синтаксического анализа, потому что это семантически неверно.
Если вы действительно хотите, чтобы лексер мог обрабатывать такие вещи, вы можете сделать что-то вроде этого:1013 *
INT
: Digit+ (Letter {/* throw an exception */})?
;
И если вы хотите, чтобы литералы INT
могли заканчиваться f
или L
, то вам сначала нужно проверить содержимое Letter
, и если это не "f"
или "L"
, вы бросаете исключение.