编译器如何工作?[关闭]


17

注意:令我感到惊讶的是,以前从未有人问过它,如果有,我在搜索中找不到它。

我去过很多网站,读过很多文章,也听过很多解释。他们中的大多数都是好人,但是他们要么太宽泛,要么太过复杂,甚至简直就是坏。所以我的问题是,编译器如何工作?

如果这是一个困难而广泛的问题,请告诉我。但是,如果没有,请回答问题。


4
范围太广,至少是“它是如何工作的”部分。有关该主题的书籍全都有。
Oded

1
en.wikipedia.org/wiki/Compiler是很容易找到的Wikipedia链接,您具体想知道什么?这个问题范围很广,我很想给出一个明智的alec响应,即“编译器将代码从一种语言翻译成另一种语言”,因为这是一个普遍的想法,一旦人们开始研究,它就会产生很多细微差别。真正涉及到什么。
JB King

1
是的,我认为答案已经很好。
杰里米

1
关于编译器如何工作的任何解释都可能太广泛或太复杂。这是一个复杂的主题,而编译器类是我参加过的与计算机相关的最难的课程。
David Thornley,

1
@David当然,编译器很复杂,您不能在这里解释它们如何工作的所有细节。但是,在您上编译器课程之前,我确定您对编译器是什么或其工作原理有基本的了解。
迪马

Answers:


24

编译器是将另一个程序的源代码从编程语言转换为可执行代码的程序。

源代码通常使用高级编程语言(例如Pascal,C,C ++,Java,Perl,C#等)。可执行代码可以是可以直接由CPU执行的一系列机器指令,也可以是由虚拟机解释的中间表示(例如Java字节码)。

简而言之,编译器将程序从人类可读格式转换为机器可读格式。

至于编译器的工作方式,这确实很复杂。有关于该主题的书籍和大学课程。我将尝试简要概述该过程的主要阶段,但这将是一个非常粗略的概述。

  1. 乐兴-将程序文本拆分为“令牌”。令牌是编程语言的“字”,例如标识符(关键字,变量名,函数名等)或运算符(=,*,&等)。
  2. 解析-将标记序列转换为解析树,这是一种表示各种语言构造的数据结构:类型声明,变量声明,函数定义,循环,条件,表达式等。
  3. 优化-评估常量表达式,优化未使用的变量或无法访问的代码,尽可能展开循环等。
  4. 将解析树转换成机器指令(或JVM字节码)。

我再次强调,这是一个非常简短的描述。现代编译器非常聪明,因此非常复杂。


2
实际上,它将一种语言转换为另一种语言。早期的C ++编译器确实可以编译为C。Vala编译器也是如此。Java编译器会编译为没有JVM的JIT编译器无法执行的字节码。
deadalnix

1
@deadalnix恕我直言,关键是您要从不可执行的代码转到可执行的代码。我认为C前端不是编译器,而是C编译器的前端。如果愿意,也可以进入编译过程的一个阶段。虚拟机当然模糊了“可执行”和“不可执行”之间的界限。在这里,我只是将可执行代码视为虚拟机中的任何内容,例如字节码,然后将VM内部的所有内容(如JIT)抽象化。
迪马

1
@Dima,它不必从非可执行代码到可执行代码。例如,您不能直接在Windows计算机上执行JVM字节代码。

1
@ThorbjørnRavn Andersen:但是字节代码可以由JVM执行。对于程序员来说,“虚拟机”的全部目的不是像一台真正的机器吗?
Dima

2
我会争辩说,传统上,如Dima所说,编译器将程序从人类可读格式转换为机器可读格式。诸如Cfront将C ++转换为C或将Java转换为字节码的javac之类的变体是更高级的主题,应该向不熟悉它的人解释基本的传统概念之前,应该保留这些变体。
2011年

5

编译器是一种计算机程序(或指令集),可以将以编程语言(源语言)编写的源代码转换为另一种计算机语言(目标语言,通常具有称为目标代码的二进制形式)。想要转换源代码的最常见原因是创建可执行程序。

编译器将高级语言的源程序与基础硬件桥接在一起。编译器要求:

  1. 确定程序语法的正确性
  2. 生成正确和有效的目标代码
  3. 运行时组织
  4. 根据汇编器和/或链接器约定格式化输出。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.