90分钟实现一门编程语言(极简解释器教程)

2019-12-30 14:54:22王冬梅

本文介绍了如何使用 C# 实现一个简化 Scheme——iScheme 及其解释器。

如果你对下面的内容感兴趣:

实现基本的词法分析,语法分析并生成抽象语法树。 实现嵌套作用域和函数调用。 解释器的基本原理。 以及一些 C# 编程技巧。

那么请继续阅读。

如果你对以下内容感兴趣:

高级的词法/语法分析技术。 类型推导/分析。 目标代码优化。

本文则过于初级,你可以跳过本文,但欢迎指出本文的错误 :-)

代码样例


public static int Add(int a, int b) {
  return a + b;
}
>> Add(3, 4)
>> 7
>> Add(5, 5)
>> 10

这段代码定义了 Add 函数,接下来的 >> 符号表示对 Add(3, 4) 进行求值,再下一行的 >> 7 表示上一行的求值结果,不同的求值用换行分开。可以把这里的 >> 理解成控制台提示符(即Terminal中的PS)。

什么是解释器

c#,极简解释器

解释器(Interpreter)是一种程序,能够读入程序并直接输出结果,如上图。相对于编译器(Compiler),解释器并不会生成目标机器代码,而是直接运行源程序,简单来说:

解释器是运行程序的程序。

计算器就是一个典型的解释器,我们把数学公式(源程序)给它,它通过运行它内部的”解释器”给我们答案。

c#,极简解释器

iScheme 编程语言

iScheme 是什么?

Scheme 语言的一个极简子集。 虽然小,但变量,算术|比较|逻辑运算,列表,函数和递归这些编程语言元素一应俱全。 非常非常慢——可以说它只是为演示本文的概念而存在。

OK,那么 Scheme 是什么?

一种函数式程序设计语言。 一种 Lisp 方言。 麻省理工学院程序设计入门课程使用的语言(参见 MIT 6.001 和 计算机程序的构造与解释)。

c#,极简解释器

使用 波兰表达式(Polish Notation)。
更多的介绍参见 [Scheme编程语言]。
以计算阶乘为例:

C#版阶乘


public static int Factorial(int n) {
  if (n == 1) {
    return 1;
  } else {
    return n * Factorial(n - 1);
  }
}

iScheme版阶乘


(def factorial (lambda (n) (
  if (= n 1)
    1
    (* n (factorial (- n 1))))))

数值类型

由于 iScheme 只是一个用于演示的语言,所以目前只提供对整数的支持。iScheme 使用 C# 的 Int64 类型作为其内部的数值表示方法。