2012-03-15 1 views
4

J'utilise ANTLR à tokenizer une grammaire simple, et la nécessité de faire la différence entre un ID:Comment différencier les mots réservés et les variables en utilisant ANTLR?

ID    : LETTER (LETTER | DIGIT)* ; 

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

et RESERVED_WORD:

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

dire que je lance le lexer sur l'entrée:

class abc 

Je reçois deux jetons d'identification pour "class" et "abc", alors que je veux que "class" soit reconnu comme RESERVED_WORD. Comment puis-je accomplir cela?

Répondre

6

Chaque fois que 2 règles (ou plus) correspondent au même nombre de caractères, celui défini en premier «gagne». Donc, si vous définissez RESERVED_WORD avant ID, comme ceci:

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' ; 

L'entrée "class" sera tokenizés comme RESERVED_WORD.

Notez que cela ne fait pas beaucoup de sens pour créer un seul jeton qui correspond à tout mot réservé: généralement, il se fait comme ceci:

// ... 

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

// ... 

ID    : LETTER (LETTER | DIGIT)* ; 

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

Maintenant "false" deviendra un jeton FALSE et "falser" un ID.

Questions connexes