ANTLR4 проблема пробелов с разделением цифр и букв - PullRequest
0 голосов
/ 23 апреля 2020

У меня есть грамматика, которая должна различать идентификаторы, INT и IP-адреса. В моей грамматике есть больше шаблонов для распознавания, но я борюсь с такими токенами, как «123ab c».

Обычно грамматика определяет WS: [\ t \ r \ n] + -> skip; который будет игнорировать пробелы, поэтому в моем грамматическом вводе, например, «123ab c» станет «123» и «ab c». Это правильное поведение лексера. Однако я хочу, чтобы в этой ситуации синтаксический анализ не удался.

Я видел похожие вопросы в SO и некоторых других сайтах. Я придумал рабочее решение (ниже), но мне кажется, что должен быть лучший способ. Интересно, может кто-нибудь предложить такой способ?

Вот моя (упрощенная) рабочая грамматика:

grammar Simple;

query: exp SP EOF;
exp: exp SP exp | term;
term: (name | sint) | name SP? '=' range_vals;
range_vals: SP? range_val SP? '..' SP? range_val;
sint: MINUS? INT;
range_val: (name | sint);
name: NAME;

MINUS: '-';
NAME: ALFA (ALFA_NUM)+;
fragment ALFA_NUM: ALFA | [0-9];
fragment ALFA: [a-z] | [A-Z];
INT: [0-9]+;

SP: ' '+;
WS: [\t\r\n]+ -> skip;
SL_COMMENT: '//' .*? '\n' -> skip;

1 Ответ

1 голос
/ 23 апреля 2020

Если 123abc создает токен INT и токен NAME, то нет способа разрешить 123 abc, но не 123abc, игнорируя при этом пробелы. Но то, что вы можете сделать, это сделать так, чтобы он вместо этого выдавал один токен, недопустимый токен, например так (поместите его после определений NAME и INT, чтобы они имели приоритет для действительных имен и номеров):

ILLEGAL_NAME: ALFA_NUM+;

Теперь 123 abc даст вам токен INT и NAME, тогда как 123abc даст вам токен ILLEGAL_NAME, который вызовет ошибку в синтаксическом анализаторе, потому что ему ничего не соответствует.

...