编译器与解释器(基于构造和设计)
在查看了很多关于编译器和解释器之间差异的帖子后,我仍然无法弄清楚它们的构造和内部机制的差异。
我读到的最常见的区别是编译器生成一个可执行的目标程序{表示机器代码作为其输出},它可以在系统上运行并且可以输入输入。 而解释器只是简单地逐行运行输入{这里到底发生了什么?}并生成输出。
我的主要疑问是:
1)编译器由词法分析器、解析器、中间代码生成器和代码生成器组成,但是解释器由哪些部分组成?
2)谁为解释性语言提供运行时支持,我的意思是谁管理递归函数的堆和堆栈?
3)这是Python语言特有的:
Python 还包括编译器阶段和解释器阶段 编译器生成一些字节码,然后该字节码由其虚拟机解释。
如果我只为Python设计编译器(Python -> 字节码)
a)我是否必须为其管理内存{编写代码来管理堆栈和堆}?
b) 这个编译器与传统编译器或解释器有何不同?
我知道这里有很多问题要问,但我真的很想了解这些细节。
我指的是 Alfred V. Aho 的编译器书
基于反馈和一些进一步的研究,我认为我应该修改我的问题
编译器不需要只生成机器代码作为其输出
但有一个问题仍然是打扰我 假设我想设计一个(Python->字节码)编译器,然后字节码将由虚拟机解释。(如果我错了,请纠正我)。
然后我必须为Python编写一个词法分析器,然后是一个解析器,它将生成某种抽象语法树..在此之后,我必须生成一些中间代码(龙书中提到的3个地址代码)或直接字节码指令(我想将在虚拟机的文档中给出)?
我是否还必须编写处理堆栈的代码以提供对递归和作用域的支持?
After viewing lots of posts about the difference between compilers and interpreters, I'm still not able to figure out the difference in their construction and internal mechanism.
The most common difference I read was that a compiler produces a target program which is executable { means machine code as its output } which can run on a system and than be fed with input.
Whereas an interpreter simply runs the input line by line { what exactly is happening here ?} and produces the output.
My main doubts are :
1) A compiler consists of a lexical analyzer, parser, intermediate code generator and code generator but what are the parts of an interpreter?
2) Who gives the run-time support to interpreted languages, I mean who manages the heap and stacks for recursive functions?
3) This is specific to the Python language:
Python comprises of a compiler stage and than interpreter stage as well
compiler produces some byte-code and and than this byte-code is interpreted by its Virtual Machine.
if I were to design only the compiler for Python (Python -> bytecode)
a) will I have to manage memory { write code to manage stack and heap } for it?
b) how will this compiler differ from the traditional compiler or say interpreter?
I know this is a whole lot to ask here but I really want to understand these minute details.
I'm referring the compiler book by Alfred V. Aho
Based on the feedback and some further study I think I should modify my question
A compiler need not produce only machine code as its output
But one question is still bugging me
Let say I want to design a ( Python->bytecode ) compiler and then bytecode will be interpreted by the virtual machine.. (correct me if I'm wrong ).
Then I'll have to write a lexical analyzer for Python and then a parser which will generate some sort of abstract syntax tree.. after this do I have to generate some intermediate code (3 address code as mentioned in the dragon book) or direct bytecode instructions ( which I suppose will be given in the VM's documentation ) ?
Will I have to write code for handling stack as well to provide support for recursion and scope ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,“编译器”并不意味着“输出机器代码”。您可以从任何语言编译为任何其他语言,无论是高级编程语言、某种中间格式、虚拟机代码(字节码)还是物理机代码(机器代码)。
像编译器一样,解释器需要阅读和理解它实现的语言。因此,您拥有相同的前端代码(尽管今天的解释器通常实现更简单的语言 - 仅字节码;因此这些解释器只需要一个非常简单的前端)。与编译器不同,解释器的后端不生成代码,而是执行它。显然,这是一个完全不同的问题,因此解释器看起来与编译器有很大不同。它模拟一台计算机(通常是比现实生活中的机器高级得多的计算机),而不是生成等效程序的表示。
假设今天的虚拟机有点高级,这是解释器的工作 - 有专门的指令用于调用函数和创建对象等,并且垃圾收集已内置到虚拟机中。当您以较低级别的机器(例如 x86 指令集)为目标时,许多此类细节需要融入到生成的代码中,无论是直接(系统调用或其他方式)还是通过调用 C 标准库实现。
3.
a) 可能不会,因为专用于 Python 的 VM 不需要它。这很容易搞砸,没有必要,而且可以说与 Python 语义不兼容,因为它允许手动内存管理。另一方面,如果您要针对诸如 LLVM 之类的低级内容,则必须特别小心 - 细节取决于目标语言。这就是为什么没有人这样做的部分原因。
b) 这将是一个完美的编译器,显然不是一个解释器。您可能拥有比针对机器代码的编译器更简单的后端,并且由于输入语言的性质,您不需要做那么多的分析和优化,但没有根本的区别。
First off, "compiler" does not imply "outputs machine code". You can compile from any language to any other, be it a high-level programming language, some intermediate format, code for a virtual machine (bytecode) or code for a physical machine (machine code).
Like a compiler, an interpreter needs to read and understand the language it implements. Thus you have the same front-end code (though today's interpreters usually implement far simpler language - the bytecode only; therefore these interpreters only need a very simple frontend). Unlike a compiler, an interpreter's backend doesn't generate code, but executes it. Obviously, this is a different problem entirely and hence an interpreter looks quite difference from a compiler. It emulates a computer (often one that's far more high-level than real life machines) instead of producing a representation of an equivalent program.
Assuming today's somewhat-high-level virtual machines, this is the job of the interpreter - there are dedicated instructions for, among other things, calling functions and creating objects, and garbage collection is baked into the VM. When you target lower-level machines (such as the x86 instruction set), many such details need to be baked into the generated code, be it directly (system calls or whatever) or via calling into the C standard library implementation.
3.
a) Probably not, as a VM dedicated to Python won't require it. It would be very easy to screw up, unnecessary and arguably incompatible to Python semantics as it allows manual memory management. On the other hand, if you were to target something low-level like LLVM, you'd have to take special care - the details depend on the target language. That's part of why nobody does it.
b) It would be a perfectly fine compiler, and obviously not an interpreter. You'd probably have a simpler backend than a compiler targeting machine code, and due to the nature of the input language you wouldn't have quite as much analysis and optimization to do, but there's no fundamental difference.