Antlr canal caché problème des espaces
-
18-09-2019 - |
Question
J'ai la grammaire Antlr suivante:
grammar MyGrammar;
doc : intro planet;
intro : 'hi';
planet : 'world';
MLCOMMENT
: '/*' ( options {greedy=false;} : . )* '*/' { $channel = HIDDEN; };
WHITESPACE : (
(' ' | '\t' | '\f')+
|
// handle newlines
( '\r\n' // DOS/Windows
| '\r' // Macintosh
| '\n' // Unix
)
)
{ $channel = HIDDEN; };
Dans les ANTLRWorks 1.2.3 interprète, le travail hi world
entrées, hi/**/world
et hi /*A*/ world
, comme prévu.
Cependant, la hiworld
d'entrée, qui ne doit pas travail, est également accepté.
Comment puis-je faire hiworld
échouer? Comment puis-je forcer au moins un des espaces (ou commentaire) entre « salut » et « monde »?
Notez que je l'ai utilisé que MLCOMMENT et WHITESPACE dans cet exemple pour simplifier, mais d'autres types de commentaires seraient pris en charge.
La solution
Vous devez créer un jeton d'identification générale. Depuis le lexer construit le plus long jeton qu'il peut, il verrait l'entrée « hiworld » en un seul mot, car il est plus que « salut » ou « monde » par eux-mêmes. Une telle règle pourrait ressembler à:
ID : ('a'..'z' | 'A'..'Z')+;
À titre d'exemple, c'est exactement comment parseurs pour les langages de programmation séparent le mot-clé « faire » de « double » (type mot-clé, commence par « faire ») ou « fait » (nom de la variable).
Autres conseils
Une façon de rendre la chaîne hiworld
fail est d'utiliser un prédicat sémantique validation qui est voué à l'échec, comme suit:
doc: intro planet;
failure : 'hiworld' { false }?;
intro : 'hi';
planet : 'world';
// rest of grammar omitted