Как я могу различить зарезервированные слова и переменные, используя ANTLR? - PullRequest
6 голосов
/ 15 марта 2012

Я использую ANTLR для токенизации простой грамматики, и мне нужно различать идентификатор:

ID              : LETTER (LETTER | DIGIT)* ;

fragment DIGIT  : '0'..'9' ;
fragment LETTER : 'a'..'z' | 'A'..'Z' ;

и RESERVED_WORD:

RESERVED_WORD : 'class' | 'public' | 'static' | 'extends' | 'void' | 'int' | 'boolean' | 'if' | 'else' | 'while' | 'return' | 'null' | 'true' | 'false' | 'this' | 'new' | 'String' ;

Скажем, я запускаю лексервходные данные:

class abc

Я получаю два токена ID для "class" и "abc", в то время как я хочу, чтобы "class" был распознан как RESERVED_WORD.Как мне это сделать?

1 Ответ

8 голосов
/ 15 марта 2012

Всякий раз, когда 2 (или более) правила соответствуют одному и тому же количеству символов, первое определенное правило «выиграет». Итак, если вы определите RESERVED_WORD до ID, например:

RESERVED_WORD : 'class' | 'public' | 'static' | 'extends' | 'void' | 'int' | 'boolean' | 'if' | 'else' | 'while' | 'return' | 'null' | 'true' | 'false' | 'this' | 'new' | 'String' ;

ID              : LETTER (LETTER | DIGIT)* ;

fragment DIGIT  : '0'..'9' ;
fragment LETTER : 'a'..'z' | 'A'..'Z' ;

Вход "class" будет размечен как RESERVED_WORD.

Обратите внимание, что не имеет смысла создавать отдельный токен, который соответствует любому зарезервированному слову: обычно это делается так:

// ...

NULL  : 'null';
TRUE  : 'true';
FALSE : 'false;

// ...

ID              : LETTER (LETTER | DIGIT)* ;

fragment DIGIT  : '0'..'9' ;
fragment LETTER : 'a'..'z' | 'A'..'Z' ;

Теперь "false" станет токеном FALSE, а "falser" * ID.

...