학습 목적으로 프로그래밍 언어를 작성하는 중입니다. 나는 이미 내 언어의 하위 집합에 대한 렉서와 재귀 강하 파서를 썼다 (나는 현재 + - * /
괄호 와 같은 수학 표현을 지원한다 ). 파서는 나에게 추상 구문 트리를 다시 건네주고, 여기 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에 게시하지 않았습니다. 내가 놓친 아이디어와 개념, 그리고 내가 어떻게 접근해야하는지 공유하기를 바랍니다.