J'ai découvert comment. Ce n'est peut-être pas la meilleure approche, mais cela semble fonctionner.
- parseurs Antlr reçoivent un paramètre
ITokenStream
- lexers Antlr sont eux-mêmes
ITokenSource
s
ITokenSource
est une interface nettement plus simple que ITokenStream
- La façon la plus simple de convertir un
ITokenSource
à un ITokenStream
est d'utiliser un CommonSourceStream
, qui reçoit un paramètre ITokenSource
Alors maintenant, nous ne devons faire 2 choses:
- Adjust la grammaire à être analyseur seulement
- Mettre en oeuvre ITokenSource
Réglage de la grammaire est très simple. Supprimez simplement toutes les déclarations lexer et assurez-vous de déclarer la grammaire comme parser grammar
. Un exemple simple est affiché ici pour convinience:
parser grammar mygrammar;
options
{
language=CSharp2;
}
@parser::namespace { MyNamespace }
document: (WORD {Console.WriteLine($WORD.text);} |
NUMBER {Console.WriteLine($NUMBER.text);})*;
Notez que le fichier suivant affichera class mygrammar
au lieu de class mygrammarParser
. Alors, nous voulons maintenant implémenter une fausse "lexer". J'ai personnellement utilisé le pseudo-code suivant:
TokenQueue q = new TokenQueue();
//Do normal lexer stuff and output to q
CommonTokenStream cts = new CommonTokenStream(q);
mygrammar g = new mygrammar(cts);
g.document();
Enfin, nous devons définir TokenQueue
. TokenQueue
n'est pas strictement nécessaire mais je l'ai utilisé pour plus de commodité. Il devrait avoir des méthodes pour recevoir les jetons lexer, et des méthodes pour sortir les jetons Antlr. Donc, si vous n'utilisez pas les jetons natifs Antlr, vous devez implémenter une méthode convert-to-Antlr-token. En outre, TokenQueue
doit implémenter ITokenSource
. Sachez qu'il est très important de définir correctement les variables de jeton. Au départ, j'ai eu quelques problèmes parce que j'avais mal calculé CharPositionInLine
. Si ces variables sont incorrectement définies, l'analyseur peut échouer. En outre, le canal normal (non masqué) est 0.
Cela semble fonctionner pour moi jusqu'à présent. J'espère que les autres le trouveront utile aussi. Je suis ouvert aux commentaires. En particulier, si vous trouvez une meilleure façon de résoudre ce problème, n'hésitez pas à poster une réponse séparée.
Ma recommandation est que vous pouvez apprendre de ceux qui existent déjà. Cependant, je ne peux trouver que NHibernate qui utilise Antlr, et l'utilisation est plutôt limitée. : " –
*" mais il y a aussi les petites parties qui ne sont pas et qui sont incroyablement douloureuses à résoudre "* - Odd La partie laxative d'une langue est généralement plus facile à implémenter Peut-être pourriez-vous expliquer ce que les" petites parties "vous donnent Problèmes? –
@Bart Kiers Je rencontre des problèmes avec l'implémentation de plages et d'autres fonctionnalités (telles que 3.toString() et 3.0.toString()) d'une manière différente de celle indiquée dans leur FAQ. Incroyablement simple à résoudre dans un lexer créé manuellement – luiscubal