4

我知道还有其他关于编译器/解释器技术的问题,以及像IronPython侏罗纪这样的非常好的代码来学习。对我来说很清楚如何从源代码构建 AST(抽象语法树),编写一个 top-descent 解析器(目前我更喜欢编写而不是使用代码生成工具)。

当用作解释器时,我尝试研究的大多数资源都使用 Reflection.Emit 之类的 API 即时编译程序。现在我想知道构建一个不编译为 .NET VM 源的真正解释器的最佳实践。

获得 AST 后,如何执行代码?我应该使用解释器还是访问者设计模式?或者做一些不同的事情?什么是最好的或规范的方式?

我知道已经有这样的问题,但如果可能的话,我喜欢更多信息和更具体的 .NET/C# 实现。

问候,贾科莫

4

1 回答 1

5

我应该使用解释器还是访问者设计模式?

我认为这些名称给出了提示;-)

访问者对 AST 的一般操作很有用,但对于执行单一功能(执行/解释),您只需要一种方法,因此需要解释器模式。

这是一个非常简单的示例(但实际上并没有比这更复杂,即使对于复杂的解释器也是如此):

// 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 回答