私は自分のプログラミング言語を作成している最中で、それは学習目的のためにしています。私はすでに自分の言語のサブセット用にレクサーと再帰降下パーサーを作成しました(現在、などの数式をサポートし+ - * /
ています)。パーサーは、抽象構文ツリーを返します。抽象ツリーでは、Evaluate
メソッドを呼び出して式の結果を取得します。すべて正常に動作します。ほぼ私の現在の状況は次のとおりです(C#のコード例、これはほとんど言語に依存しません):
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;
}
}
ただし、Open / Closed Principleを適用したいため、アルゴリズムをツリーノードから分離したいので、たとえばコード生成を実装するときにすべてのノードクラスを再度開く必要はありません。訪問者パターンはそのために良いと読みました。私はパターンがどのように機能するかについて十分に理解しており、ダブルディスパッチを使用することがその方法であることを理解しています。しかし、ツリーの再帰的な性質のため、どのようにアプローチすべきかわかりません。私の訪問者は次のようになります。
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
}
これが私の問題です。後で大きな問題が発生するのを避けるために、私の言語が多くの機能をサポートしていない間、私はすぐにそれに取り組みたいです。
実装を提供したくないので、これをStackOverflowに投稿しませんでした。私が見落としていたかもしれないアイデアや概念、そしてこれにどうアプローチするかだけを共有してほしい。