Je suis en train de créer mon propre langage de programmation, ce que je fais à des fins d'apprentissage. J'ai déjà écrit le lexer et un analyseur de descente récursif pour un sous-ensemble de ma langue (je supporte actuellement les expressions mathématiques, telles que + - * /
et les parenthèses). L'analyseur me rend un arbre de syntaxe abstraite, sur lequel j'appelle la Evaluate
méthode pour obtenir le résultat de l'expression. Tout fonctionne bien. Voici approximativement ma situation actuelle (exemples de code en C #, bien que cela soit à peu près indépendant du langage):
public abstract class Node
{
public abstract Double Evaluate();
}
public class OperationNode : Node
{
public Node Left { get; set; }
private String Operator { get; set; }
private Node Right { get; set; }
public Double Evaluate()
{
if (Operator == "+")
return Left.Evaluate() + Right.Evaluate();
//Same logic for the other operators
}
}
public class NumberNode : Node
{
public Double Value { get; set; }
public Double Evaluate()
{
return Value;
}
}
Cependant, je voudrais découpler l'algorithme des nœuds d'arbre parce que je veux appliquer le principe ouvert / fermé, donc je n'ai pas à rouvrir chaque classe de nœuds lorsque je veux implémenter la génération de code par exemple. J'ai lu que le modèle de visiteur est bon pour cela. J'ai une bonne compréhension du fonctionnement du modèle et de l'utilisation de la double répartition. Mais en raison de la nature récursive de l'arbre, je ne sais pas comment je dois l'approcher. Voici à quoi ressemblerait mon visiteur:
public class AstEvaluationVisitor
{
public void VisitOperation(OperationNode node)
{
// Here is where I operate on the operation node.
// How do I implement this method?
// OperationNode has two child nodes, which may have other children
// How do I work the Visitor Pattern around a recursive structure?
// Should I access children nodes here and call their Accept method so they get visited?
// Or should their Accept method be called from their parent's Accept?
}
// Other Visit implementation by Node type
}
C'est donc mon problème. Je veux y faire face immédiatement alors que ma langue ne supporte pas beaucoup de fonctionnalités pour éviter d'avoir un problème plus important plus tard.
Je n'ai pas posté ceci sur StackOverflow car je ne veux pas que vous fournissiez une implémentation. Je veux seulement que vous partagiez des idées et des concepts que j'aurais pu manquer et comment je devrais aborder cela.