J'essaie de faire correspondre les mesures dans le texte d'entrée en anglais, en utilisant Antlr 3.2 et Java1.6. J'ai des règles lexicales comme ce qui suit:Variantes lexème correspondantes avec Antlr3
fragment
MILLIMETRE
: 'millimetre' | 'millimetres'
| 'millimeter' | 'millimeters'
| 'mm'
;
MEASUREMENT
: MILLIMETRE | CENTIMETRE | ... ;
Je voudrais être en mesure d'accepter toute combinaison d'entrée en minuscules et majuscules et - plus important encore - il suffit de retourner un seul jeton lexical pour toutes les variantes de MILLIMÈTRE. Mais pour l'instant, mon AST contient «millimètre», «millimètre», «mm», etc., tout comme dans le texte d'entrée.
Après avoir lu http://www.antlr.org/wiki/pages/viewpage.action?pageId=1802308, je pense que je dois faire quelque chose comme ce qui suit:
tokens {
T_MILLIMETRE;
}
fragment
MILLIMETRE
: ('millimetre' | 'millimetres'
| 'millimeter' | 'millimeters'
| 'mm') { $type = T_MILLIMETRE; }
;
Cependant, quand je le fais, je reçois les erreurs du compilateur suivantes dans le code Java généré par Antlr:
cannot find symbol
_type = T_MILLIMETRE;
J'ai essayé ce qui suit à la place:
MEASUREMENT
: MILLIMETRE { $type = T_MILLIMETRE; }
| ...
mais alors MEASUREMENT ne correspond plus.
La solution la plus évidente avec une règle de réécriture:
MEASUREMENT
: MILLIMETRE -> ^(T_MILLIMETRE MILLIMETRE)
| ...
provoque une NPE:
java.lang.NullPointerException at org.antlr.grammar.v2.DefineGrammarItemsWalker.alternative(DefineGrammarItemsWalker.java:1555).
Faire MESURE en règle de l'analyseur me donne la redoutée « Les définitions symboliques suivantes ne pourra jamais égaler car les jetons antérieurs correspondent à la même erreur "d'entrée".
En créant une règle d'analyseur
measurement : T_MILLIMETRE | ...
je reçois l'avertissement "pas de règle de lexer correspondant à jeton: T_MILLIMETRE". Antlr fonctionne bien, mais il me donne toujours le texte d'entrée dans l'AST et non pas T_MILLIMETRE. Je ne vois évidemment pas encore le monde comme le fait Antlr. Quelqu'un peut-il me donner des conseils ou des conseils s'il vous plaît?
Steve
Merci pour votre réponse, Bart. J'étais au courant de cette possibilité. La différence est que j'essaie de résoudre le problème au niveau lexical, alors que vous proposez une règle syntaxique. Votre chemin est probablement la bonne façon Antlr. Mon expérience avec ce problème est que les règles de réécriture ne fonctionnent qu'avec des règles syntaxiques, et non avec des règles lexicales. Je suis en train de résoudre le problème dans ma solution en post-traitant les résultats dans mon code Java, mais je devrais peut-être reconsidérer ce que je fais dans Antlr au niveau lexical et ce que je fais au niveau syntaxique. –
@Stephen, ah d'accord, je vois ce que tu veux dire. Mais dans mon exemple, le type (pour le millimètre) sera toujours 'MilliMeter' (voir mon ** EDIT **). Donc, je ne suis pas tout à fait sûr de ce que vous cherchez. –
Vous m'avez fait réfléchir, Bart. J'abordais le problème de la mauvaise façon. J'essayais de faire une reconnaissance ascendante efficace en rendant l'analyse lexicale sensible au contexte. Cela a signifié que j'ai rapidement atteint les limites de ce qu'Antlr pouvait faire, puisqu'il s'agit d'un outil top-down. J'ai transféré beaucoup de l'analyse dans la syntaxe maintenant (comme dans votre exemple), et tout devient plus facile. Je pense qu'il faut être très conscient de la différence entre les règles lexicales et les règles syntaxiques dans Antlr, même si elles sont très similaires. Tout ce que les règles syntaxiques peuvent faire n'est pas possible avec les règles lexicales. –