4

コンパイラ/インタプリタテクノロジについて他にも質問があり、IronPythonからJurassicのように学習するのに非常に優れたコードがあることも知っています。私には、ソースからAST(抽象構文木)を構築し、トップディセントパーサーを作成する方法が非常に明確です(現時点では、コード生成ツールを使用するよりも作成する方が好きです)。

インタープリターとして使用するときに私が研究しようとしているほとんどのソースは、Reflection.EmitなどのAPIを使用してプログラムをオンザフライでコンパイルします。ここで、ソースの.NETVMにコンパイルされない実際のインタープリターを構築するためのベストプラクティスを知りたいと思います。

ASTを取得したら、どうすればコードを実行できますか?通訳または訪問者のデザインパターンを使用する必要がありますか?それとも何か違うことをしていますか?最善または標準的な方法は何ですか?

私はすでにこのような質問があることを知っていますが、可能であれば、より多くの情報と.NET / C#実装に固有のものが好きです。

よろしく、ジャコモ

4

1 に答える 1

5

通訳または訪問者のデザインパターンを使用する必要がありますか?

名前はヒントを与えると思います;-)

訪問者はASTの一般的な操作には適していますが、単一の機能(実行/解釈)を実行するには、1つのメソッド、つまりインタープリターパターンが必要です。

これは非常に単純な例です(ただし、複雑な通訳者であっても、実際にはそれ以上に複雑になることはありません)。

// Holds function scope etc.
class Context {}

abstract class Node {
    public abstract object Execute(Context ctx);
}

class Number : Node {
    private readonly int x;

    public Number(int x) { this.x = x; }

    public override object Execute(Context ctx) { return x; }
}

class Addition : Node {
    private readonly Node left, right;

    public Addition(Node left, Node right) {
        this.left = left;
        this.right = right;
    }

    public override object Execute(Context ctx) {
        // Verification omitted: do the nested expressions evaluate to a number?
        return (int) left.Execute(ctx) + (int) right.Execute(ctx);
    }
}

…そしてあなたはそれを持っています。足し算を知っているシンプルな通訳。そして、これが使用例です:

var ast = new Addition(new Number(23), new Number(42));
Console.WriteLine("Result = {0}", ast.Execute(new Context()));
于 2012-12-21T11:15:40.630 に答える