Использование нескольких команд лексера в одном правиле лексера в Antlr - PullRequest
1 голос
/ 07 мая 2020

Я пытаюсь использовать более одной команды лексера в правиле лексера. Мой код выглядит примерно так:

LEXER_RULE: something->mode(NUMBER);

mode NUMBER;
NU: [0-9]+ ->mode(ANOTHER_MODE); //Going into another mode in case the NU rule is used

//now leaving the NUMBER mode, in case there is no number written

NO_NUM: ~[0-9]->mode(DEFAULT_MODE);

Правило лексера NU является необязательным, поэтому я должен рассмотреть случай, когда он не используется. Однако я бы также хотел пропустить все, что находится внутри NO_NUM. Что-то вроде

NO_NUM:~[0-9]->skip ->mode(DEFAULT_MODE);

Я знаю, что мне нельзя использовать более одной команды лексера в одном правиле лексера. Кто-нибудь знает другой подход? Мне нужно как-то выйти из режима. Кстати, мне не разрешено использовать предикаты semanti c. Спасибо!

1 Ответ

1 голос
/ 07 мая 2020

Вы были почти у цели! Используйте вставку через запятую:

NO_NUM : ~[0-9] -> skip, mode(DEFAULT_MODE);

Это, очевидно, отбрасывает все, что соответствует ~[0-9]. Итак, если у вас есть эта грамматика:

ID : [a-zA-Z]+;
...

mode NUMBER;
  NU.    : [0-9]+ -> mode(ANOTHER_MODE);
  NO_NUM : ~[0-9] -> skip, mode(DEFAULT_MODE);

mode ANOTHER_MODE;
  ...

А в mode NUMBER вы встречаете abc, тогда a отбрасывается, а bc будет преобразован в ID. Если вы также хотите, чтобы a был частью ID, вам необходимо сделать это:

ID : [a-zA-Z]+;
...

mode NUMBER;
  NU.    : [0-9]+ -> mode(ANOTHER_MODE);
  NO_NUM : ~[0-9] -> more, mode(DEFAULT_MODE);

mode ANOTHER_MODE;
  ...

Подробнее о Lexer Command: https://github.com/antlr/antlr4/blob/master/doc/lexer-rules.md#lexer -команды

...