ほとんどのコンパイラは、次のいずれかを使用してこの問題を解決します。
式に現れるすべての定数値 (リテラル) をList
整数の に収集する方法を次に示します。コードを呼び出すと、このリストの値をテキスト ボックスに入力できます。
メソッドのオーバーライド
最上位の AST クラスは、サブクラスでオーバーライドされる抽象メソッドを定義します。
class AstNode {
.. // Some stuff
public abstract void collectValues(List<Integer> ints);
}
class ConstantExpression : AstNode {
private int value;
.. // Some stuff
public override void collectValues(List<Integer> ints) { ints.Add(value); }
}
class BinaryExpression : AstNode {
private AstNode left;
private AstNode right;
.. // Some stuff
public override void collectValues(List<Integer> ints) {
left.collectValues(ints);
right.collectValues(ints);
}
}
class Identifier : AstNode {
.. // Some stuff
public override void collectValues(List<Integer> ints) {
// do nothing!
}
}
ビジター
同じプログラムですが、訪問者を使用して記述されています。
class Visitor {
public abstract void visit(ConstantExpression e);
public abstract void visit(BinaryExpression e);
public abstract void visit(Identifier e);
}
class AstNode {
.. // Some stuff
public abstract void accept(Visitor v);
}
class ConstantExpression : AstNode {
public int value;
.. // Some stuff
public override void accept(Visitor v) { v.visit(this); }
}
class BinaryExpression : AstNode {
private AstNode left;
private AstNode right;
.. // Some stuff
public override void accept(Visitor v) {
left.accept(v);
right.accept(v);
v.visit(this);
}
}
class Identifier : AstNode {
.. // Some stuff
public override void accept(Visitor v) { v.visit(this); }
}
class ValueCollector : Visitor {
public List<Integer> ints = ...;
public void visit(ConstantExpression e) { ints.Add(e.value); }
public void visit(BinaryExpression e) { }
public void visit(Identifier e) { }
}