Выборочная обработка пробелов в ANTLR4 с помощью Python3 - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь разобрать следующую грамматику.

let_expr : LET iden integer;
CHAR     : ('a' .. 'z') | ('A' .. 'Z');
DIGIT    : ('0' .. '9');
LET      : 'let'
integer  : DIGIT+;
iden     : CHAR (CHAR|DIGIT)*;
WS       : (' ' | '\n' | '\t' | '\r')+ -> skip;

В противном случае важно игнорирование пробелов, так как это небольшой фрагмент большой грамматики, а перенос маркеров пробелов повсюду чрезвычайно громоздок.Однако, когда анализатор пытается проанализировать оператор, такой как let ab 10, он, естественно, игнорирует все пробелы между ab и 10 и анализирует ab1 как идентификатор, а последний 0 - как целое число.Очевидно, что намерение состоит в том, что ab является идентификатором, а 10 является целым числом.Я видел некоторые решения, основанные на Java, но как мне решить эту проблему в Python3?

1 Ответ

0 голосов
/ 04 декабря 2018

Сделайте integer и ident токены и CHAR и DIGIT фрагменты.Пробелы не будут игнорироваться внутри токенов, так что это решит вашу проблему.Это также решит еще одну проблему, которую вы еще не заметили:

С вашей текущей грамматикой letter будет интерпретироваться как ключевое слово let, за которым следует идентификатор ter.Это связано с тем, что в начале этого ввода у лексера есть выбор между совпадением l в качестве CHAR токена или совпадением let в качестве LET токена.При таком выборе лексер всегда предпочитает более длинное совпадение (это называется правилом максимального жаворонка).Вот почему иметь свои токены в качестве отдельных персонажей - это вообще плохая идея.Если вы создаете идентификаторы и целые числа для своих токенов, то правило максимального жаворонка будет делать то, что вы хотите, вместо того, чтобы работать против вас.

...