假设赋值的目的是编写一个适用于C语言子集的编译器(您可以假设任何语言的子集,只支持基本的脚本表达性,而不需要将复杂的东西作为对象)。
可以使用哪种中间代码来验证编译器的正确性?我正在和一位教授谈话,他谈到了这样一个事实:他不知道该给学生们什么作为用于“编译代码”的VM,所以我想知道哪个可能是一个很好的解决方案。
Subset of C -> Compiler -> Code? -> VM
其中代码可以是二进制格式,也可以是ASCII格式(类似伪asm)。
我正在寻找已经制作的东西,而不是如何构建这个中间代码和VM,只是一个简单而简单的方法,可以用来测试一些已编译的程序..
答案 0 :(得分:2)
您可以描述一些抽象的机器设计,然后以列表格式提供它的指令集。我的小LISP解析器是解析器中的nobrainer。
(label add-two)
(init-stack-frame 2)
(load r1 0)
(load r2 1)
(add val r1 r2)
(goto cont)
另外,编写一个lisp解释器来读取它是一个nobrainer。
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)
答案 1 :(得分:1)
您可以在现有VM中找到许多中间代码/ bytecode的示例。根据您的定义,它们可能简单也可能不简单。例子:
答案 2 :(得分:0)
如何编译脚本语言(例如JavaScript)?它是人类可读的并且已经制作完成。
答案 3 :(得分:0)
如何定位Java虚拟机?不知道它有多简单,但它有很好的记录,所以如果学生好奇,他们可以前往amazon.com并获得一本关于中间代码实际意义和vm如何工作的书。
您也可以创建真正的80x86或68000程序集,使用汇编程序获取机器代码,然后使用模拟器运行它。如果您已经编写了一个编译器并且它已经有大量的调试器和其他实用程序可用,那么真正的硬件并不会让我觉得比一些虚拟虚拟机更复杂。
但我确实喜欢LISP的建议: - )
答案 4 :(得分:0)
llvm怎么样?