Как указать несколько правил лексера в одном правиле?
У меня такое правило парсера:
declaration : (KW_VARIABLE DT_IDENTIFIER) |
(KW_VARIABLE DT_IDENTIFIER OP_ASSIGNMENT DT_DATA_TYPES) OP_SEMICOLON;
и следующие правила лексера:
KW_VARIABLE : 'var';
OP_ASSIGNMENT : '=';
OP_SEMICOLON : ';';
DT_IDENTIFIER : [a-z]+;
DT_INTEGER : [0-9]+;
DT_DATA_TYPES : (DT_IDENTIFIER | DT_INTEGER);
С помощью приведенных выше правил я хочу написать следующий код:
var a = 10;
var b = 40;
var c = 50;
var d = c;
Мой код слушателя для выхода из объявления выглядит так:
public override void ExitDeclaration([NotNull] PyroParser.DeclarationContext context)
{
bool isAssigned = context.OP_ASSIGNMENT() != null;
if (!isAssigned)
{
return;
}
Console.WriteLine(context.DT_DATA_TYPES().GetText());
base.ExitDeclaration(context);
}
Я получаю сообщение об ошибке в первой строке, когда бегу и говорю:
строка 1:8 несоответствующий ввод '10' ожидает DT_DATA_TYPES
Я просто хочу иметь возможность ссылаться на все типы данных в одном правиле, как я могу это сделать?
1 ответ
Это неверно:
DT_IDENTIFIER : [a-z]+;
DT_INTEGER : [0-9]+;
DT_DATA_TYPES : (DT_IDENTIFIER | DT_INTEGER);
Когда DT_IDENTIFIER
или DT_INTEGER
совпадает, он никогда не станет DT_DATA_TYPES
. Лексер сопоставляет правила сверху вниз, и как только совпадение будет найдено, он не откажется от него. И просто изменив порядок правил:
DT_DATA_TYPES : (DT_IDENTIFIER | DT_INTEGER);
DT_IDENTIFIER : [a-z]+;
DT_INTEGER : [0-9]+;
тоже не будет работать: таким образом лексер никогда не произведет DT_IDENTIFIER
а также DT_INTEGER
жетоны.
Вместо этого вы можете сделать что-то вроде этого:
dt_data_types : (DT_IDENTIFIER | DT_INTEGER);
DT_IDENTIFIER : [a-z]+;
DT_INTEGER : [0-9]+;