从AST中使用c#制作一个真正的解释器

本文关键字:一个 解释器 AST | 更新日期: 2023-09-27 17:49:22

我知道还有其他关于编译器/解释器技术的问题,也有非常好的代码可以学习,比如IronPython到Jurassic。对我来说,很清楚如何从源代码构建AST(抽象语法树),编写一个自上而下的解析器(目前我更喜欢编写而不是使用代码生成工具)。

我试图研究的大多数资源,当用作解释器时,使用API(如Reflection.Emit)编译程序。现在我想知道构建一个真正的解释器的最佳实践,不编译到。net VM的源代码。

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

我知道已经有一个这样的问题了,但如果可能的话,我想要更多的信息和更具体的。net/c#实现。

问候,Giacomo

从AST中使用c#制作一个真正的解释器

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

我认为这些名字给了一个提示;-)

访问器适用于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()));