Sono in procinto di creare il mio linguaggio di programmazione, che faccio a fini di apprendimento. Ho già scritto il lexer e un parser di discendenza ricorsiva per un sottoinsieme della mia lingua (attualmente supporto espressioni matematiche, come + - * /
parentesi). Il parser mi restituisce un albero di sintassi astratto, sul quale chiamo il Evaluate
metodo per ottenere il risultato dell'espressione. Tutto funziona bene. Ecco approssimativamente la mia situazione attuale (esempi di codice in C #, sebbene questo sia praticamente indipendente dal linguaggio):
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;
}
}
Tuttavia, desidero disaccoppiare l'algoritmo dai nodi dell'albero perché voglio applicare il principio aperto / chiuso, quindi non devo riaprire tutte le classi di nodi quando voglio implementare la generazione di codice, ad esempio. Ho letto che il modello visitatore è buono per questo. Ho una buona comprensione di come funziona il modello e che l'uso della doppia spedizione è la strada da percorrere. Ma a causa della natura ricorsiva dell'albero, non sono sicuro di come dovrei affrontarlo. Ecco come sarebbe il mio visitatore:
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
}
Quindi questo è il mio problema. Voglio affrontarlo immediatamente mentre la mia lingua non supporta molte funzionalità per evitare di avere un problema più grande in seguito.
Non l'ho pubblicato su StackOverflow perché non voglio che tu fornisca un'implementazione. Voglio solo che tu condivida idee e concetti che potrei aver perso, e come dovrei affrontarlo.