ANTLR 4 лексера токены внутри других токенов

У меня есть следующая грамматика для ANTLR 4:

grammar Pattern;

//parser rules
parse   : string LBRACK CHAR DASH CHAR RBRACK ;
string  : (CHAR | DASH)+ ;

//lexer rules
DASH    : '-' ;
LBRACK  : '[' ;
RBRACK  : ']' ;
CHAR    : [A-Za-z0-9] ;

И я пытаюсь разобрать следующую строку

ab-cd[0-9]

Код разбирает ab-cd слева, который будет рассматриваться как буквальная строка в моем приложении. Затем он разбирает [0-9] как набор символов, который в этом случае будет переводиться на любую цифру. Моя грамматика работает для меня, за исключением того, что я не люблю иметь (CHAR | DASH)+ как правило синтаксического анализа, когда это просто рассматривается как токен. Я бы предпочел лексер создать STRING токен и дайте мне следующие токены:

"ab-cd" "[" "0" "-" "9" "]"

вместо этих

"ab" "-" "cd" "[" "0" "-" "9" "]"

Я посмотрел на другие примеры, но не смог понять это. Обычно другие примеры имеют кавычки вокруг таких строковых литералов или имеют пробелы, чтобы помочь разграничить вводимые данные. Я хотел бы избежать обоих. Можно ли это сделать с помощью правил лексера или мне нужно продолжать обрабатывать это в правилах синтаксического анализатора, как я делаю?

1 ответ

Решение

В ANTLR 4 вы можете использовать режимы лексера для этого.

STRING : [a-z-]+;
LBRACK : '[' -> pushMode(CharSet);

mode CharSet;

DASH : '-';
NUMBER : [0-9]+;
RBRACK : ']' -> popMode;

После разбора [ персонаж, лексер будет работать в режиме CharSet до ] характер достигнут и popMode команда выполнена.

Другие вопросы по тегам