3

假设赋值的目的是编写一个可以在 C 语言子集上工作的编译器(您可以假设任何语言的子集,只支持基本的脚本表达能力,而无需将复杂的事物作为对象)。

什么样的中间代码可以用来验证编译器的正确性?我正在与一位教授交谈,他谈到了这样一个事实,即他不知道该给他的学生什么作为用于“编译代码”的 VM,所以我想知道哪个可能是一个好的解决方案。

Subset of C -> Compiler -> Code? -> VM

其中代码可以是二进制格式,也可以是更好的 ASCII 格式(类似于伪 asm)。

我正在寻找已经制作的东西,而不是如何构建这个中间代码和 VM,只是一个简单易用的,可以用来测试一些已编译的程序..

4

5 回答 5

2

您可以描述一些抽象的机器设计,然后以列表格式为其提供指令集。我的小型 LISP 解析器是解析器中的聪明人。

(label add-two)
(init-stack-frame 2)
(load r1 0)
(load r2 1)
(add val r1 r2)
(goto cont)

此外,编写一个 lisp 解释器来读取它是一件轻而易举的事。

load_labels (index, expr, env)
    if expr.first == 'label'
        env.set(expr.second, index)

interpret (machine, expr, env)
    return env.lookup(expr.first).eval(machine, expr.tail)
于 2010-07-19T15:37:39.570 回答
1

您可以在现有 VM中找到许多中间代码/字节码示例。根据您的定义,它们可能简单,也可能不简单。例子:

于 2010-07-19T15:52:48.480 回答
0

编译成脚本语言(例如 JavaScript)怎么样?它是人类可读的并且已经制作好了。

于 2010-07-19T15:18:47.867 回答
0

llvm怎么样?

于 2010-07-19T15:43:41.777 回答
0

以 Java 虚拟机为目标怎么样?不知道它有多简单,但它有很好的文档记录,所以如果学生好奇,他们可以前往 amazon.com 并获得一本关于中间代码实际含义以及 vm 如何工作的书。

您也可以只创建真正的 80x86 或 68000 程序集,使用汇编程序获取机器代码,然后使用仿真器运行它。如果您已经完成了编译器的编写,并且它已经拥有大量的调试器和其他实用程序,那么真正的硬件并不比一些虚构的 VM 更复杂。

但我确实喜欢 LISP 的建议 :-)

于 2010-07-19T15:38:07.630 回答