Когда я запускаю:
lexer = DecafLexer(ant.InputStream('(x + y)'))
token = lexer.nextToken()
while token.type != -1:
print(lexer.symbolicNames[token.type])
token = lexer.nextToken()
, печатается следующее:
LROUND
ID
PLUS
ID
RROUND
Я предполагаю, что вы не сгенерировали новые классы анализатора и лексера из своей грамматики.
Еще одна вещь: попробуйте токенизировать ввод boolean
: вы увидите, что он токенизирован как ID
. Это потому, что вы определили ID
перед всеми ключевыми словами (например, boolean
, false
, void
и т. Д.). Если F ANTLR может соответствовать нескольким правилам лексического анализатора (т. Е. 2 или более правил соответствуют одним и тем же символам), то «выиграет» правило, определенное первым.
Решение: переместите ID
ниже всех ключевых слов:
CLASS: 'class';
BOOLEAN : 'boolean';
BREAK : 'break';
CALLOUT : 'callout';
CONTINUE : 'continue';
ELSE : 'else';
FALSE : 'false';
FOR : 'for';
IF : 'if';
INT : 'int';
RETURN : 'return';
TRUE : 'true';
VOID : 'void';
ID : ALPHA( ALPHA | DIGIT)* ;
Наконец, это правило:
CHAR : ALPHA|DIGIT|' '| '#' | '$' | '&' | '.' | ':' | '?' | '@' | '\\' | '^' | '_' | '`'| '|' | '~' | '\t'| '\n' ;
нечетное: оно может соответствовать одиночным пробелам , но вы уже указали пропускать пробелы ранее. Кроме того, вы говорите, что он соответствует одному ALPHA
или DIGIT
, но они соответствуют ID
или NUM
соответственно.
есть T_0 и T_1, созданные перед num ID ect, который сбрасывает все на двоих, есть идеи, что это такое?
Если вы определяете буквальные токены внутри правил парсера, например:
parser_rule
: LEXER_RULE ';'
;
тогда это ';'
будет неявно определен ANTLR, как такой T_...
токен за кулисами. Но эти T_...
токены не влияют на предложения из моего ответа.