我最近阅读了整本《龙之书》(只是为了好玩,我并没有真正打算实现一个实际的编译器),我的脑海中留下了一个悬而未决的大问题。
实现编译器和解释器有什么不同?
对我来说,编译器由以下部分组成:
- 词法分析器
- 解析器(构建语法树)
- 生成中间码(如 3 地址码)
- 如果你愿意,可以做所有这些疯狂的事情来优化:-)
- 从 3 地址码生成“汇编”或“本机代码”。
现在,很明显,解释器也具有与编译器相同的词法分析器和解析器。
但在那之后它会做什么?
它是否“读取”语法树并直接执行它?(有点像有一个指向树中当前节点的指令指针,执行是一个大树遍历加上调用堆栈的内存管理)(如果是这样,它是如何做到的?我希望执行比检查它是什么类型的节点的巨大 switch 语句更好)
它会生成 3 个地址代码并对其进行解释吗?(如果是这样,它是如何做到的?同样,我正在寻找比一英里长的 switch 语句更优雅的东西)
- 它会生成真正的本机代码,将其加载到内存中并使其运行吗?(此时我猜它不再是解释器,而更像是 JIT 编译器)
另外,“虚拟机”的概念是在什么时候切入的?您在语言中使用虚拟机做什么?(要清楚我的无知程度,对我来说虚拟机是VMWare,我不知道VM的概念如何应用于编程语言/执行程序)。
如您所见,我的问题非常广泛。我主要不仅在寻找使用哪种方法,而且主要是首先了解大概念,然后详细了解它的工作原理。我想要丑陋的原始细节。显然,这更多的是寻求参考要阅读的内容,而不是期望您在这里回答所有这些细节。
谢谢!
丹尼尔
编辑:谢谢你到目前为止的回答。但我意识到我的标题具有误导性。我了解编译器和解释器之间的“功能”差异。
我正在寻找的是您如何实现解释器与编译器的区别。
我现在了解编译器是如何实现的,问题是解释器与它有何不同。
例如:VB6 显然既是编译器又是解释器。我现在了解编译器部分。但是,我无法理解,当在 IDE 中运行时,它可以让我在任意点停止程序、更改代码并使用新代码恢复执行。这只是一个很小的例子,这不是我正在寻找的答案。正如我在下面解释的那样,我试图理解的是在我拥有解析树之后会发生什么。编译器将从它以“目标”语言生成新代码。口译员做什么的?
感谢您的帮助!