web-dev-qa-db-fra.com

Auditeurs et visiteurs Antlr4 - lequel mettre en œuvre?

Je lis "The Definitive Antlr 4 Reference" et j'ai une idée de la façon dont fonctionnent les auditeurs et les visiteurs. Le livre explique particulièrement bien comment les écouteurs sont liés aux analyseurs SAX et indique clairement quand les méthodes vont être appelées lors de la mise en œuvre de chacune. Je peux également voir que les écouteurs sont assez bons pour transformer l'entrée en sortie, mais j'apprécierais une courte explication/un exemple sur le moment d'utiliser un écouteur et le moment d'utiliser un visiteur (ou devraient-ils tous les deux être utilisés dans certains cas?).

Mon intention particulière est de créer un interpréteur (Cucumber-style/TinyBasic Interpreter avec certains appels personnalisés) qui vérifiera les erreurs de syntaxe et cessera de s'exécuter sur une erreur d'une fonction personnalisée sans récupérer - j'aimerais voir une implémentation complète d'une telle chose in antlr - si quelqu'un en connaît un.

Merci d'avance pour tout conseil.

45
KevinY

Si vous prévoyez d'utiliser directement la sortie de l'analyseur pour l'interprétation, le visiteur est un bon choix. Vous avez un contrôle total sur la traversée, donc dans les conditions, une seule branche est visitée, les boucles peuvent être visitées n fois et ainsi de suite.

Si vous traduisez l'entrée à un niveau inférieur, par exemple instructions de la machine virtuelle, les deux modèles peuvent être utiles.

Vous pouvez jeter un oeil à "Modèles d'implémentation du langage", qui couvre les implémentations de base de l'interpréteur.

J'utilise principalement le modèle de visiteur, car il est plus flexible.

34
FreeJack

Voici une citation du livre qui je pense est pertinente:

La plus grande différence entre les mécanismes d'écoute et de visiteur est que les méthodes d'écoute sont appelées par l'objet walker fourni par ANTLR, tandis que les méthodes de visiteur doivent accompagner leurs enfants avec des appels de visite explicites. Oublier d'invoquer visit () sur les enfants d'un nœud signifie que ces sous-arbres ne sont pas visités.

Dans le modèle de visiteur, vous avez la possibilité de diriger la marche des arbres tandis que dans l'auditeur, vous ne réagissez qu'au marcheur des arbres.

52
Evgeni Petrov

Il y a une autre différence importante entre ces deux modèles: un visiteur utilise pile d'appel pour gérer les traversées des arbres, tandis que l'auditeur utilise une pile explicite allouée sur le tas, gérée par un marcheur . Cela signifie que de grandes entrées pour un visiteur pourraient faire exploser la pile, tandis qu'un auditeur n'aurait aucun problème.

Si vos entrées peuvent être potentiellement illimitées, ou si vous pouvez appeler votre visiteur très profondément dans une arborescence d'appels, vous devez utiliser un écouteur, plutôt qu'un visiteur, ou au moins valider que l'arbre d'analyse n'est pas trop profond. Les pratiques de codage de certaines entreprises découragent ou même interdisent carrément la récursion non-queue pour cette raison.

12
Alex Reinking

Extrait du livre, page 120.

Les visiteurs fonctionnent très bien si nous avons besoin de valeurs de retour spécifiques à l'application, car nous pouvons utiliser le mécanisme de valeur de retour intégré Java. Si nous préférons ne pas avoir à invoquer explicitement les méthodes des visiteurs pour rendre visite aux enfants, nous peut basculer vers le mécanisme d'écoute. Malheureusement, cela signifie renoncer à la propreté de l'utilisation des valeurs de retour de la méthode Java.

C'est pourquoi j'utilise des visiteurs.

0
p_champ