编译器如何编译编译器?

Posted

技术标签:

【中文标题】编译器如何编译编译器?【英文标题】:How does a compiler compile a compiler? 【发布时间】:2013-07-10 06:23:12 【问题描述】:

来自高级编程背景,我对学习低级编程很感兴趣。我想知道一个编译器是怎么编译的?

看了wiki上的一些文章,Numerical machine code据说是最底层的语言,但是必须有编译器来编译这个机器码。该编译器是用什么语言编写的?

【问题讨论】:

机器码不需要编译。它直接由CPU执行。您可以使用十六进制编辑器输入它。 Numerical machine code (i.e. not assembly code) may be regarded as the lowest-level representation of a compiled and/or assembled computer program ,来自文章第 2 段 是的,最低级别 - 没有更低的级别。这是其他语言编译成的 你的引用是说数字机器代码是程序编译的结果。没有将机器代码作为输入的编译器。 是的,当然有编译机器码的编译器:指令解码器。在现代 CPU(尤其是 x86 系)中,解码器可能非常复杂,它将指令分解为微指令序列,然后对其进行分析(以获得依赖关系和潜在危险)并发送到不同的执行单元。 【参考方案1】:

数字机器码是二进制的。 1 和 0。编译意味着将其缩减为某种更低的形式,因此它并没有真正编译。

例如,从您引用的 wiki 文章中: For example, on the Zilog Z80 processor, the machine code 00000101, which causes the CPU to decrement the B processor register, would be represented in assembly language as DEC B.

所以你在编写 Z80 汇编语言时会有一个编译器,指令 DEC B 将被编译为 '00000101' -- 反之则不然。

【讨论】:

【参考方案2】:

你总是可以使用你最喜欢的编译器 A 来编写另一个编译器,比如 B。在这个 B 中,你添加了一些额外的功能,所以它很容易成为你最喜欢的,你将用它来编写编译器 C,...

那如何开始呢? 在过去,人们只是用原始数字填充内存,由 CPU 直接解释。这就是为什么源代码通常被称为code。 一旦以这种方式编写了一个最小编译器,就可以执行它来创建另一个用它编译的语言编写的编译器。 这又可以用来创建更高级别的一个等等。

事实上,将原始指令代码填充到内存本身可以被视为零级编译过程,其中人是编译器。

给定语言的编译器通常是用相同的语言编写的。例如,C 编程语言就是这种情况。这不仅仅是巧合,因为谁知道一种语言足够好,敢为它编写编译器,很可能在他最喜欢的语言中使用这种语言进行编程。 不过这只是一个典型案例,没有必要,因为有很多语言可供选择,包括特别适合编译器构建的语言。

【讨论】:

【参考方案3】:

数字机器码代表电路的一系列关闭和开启状态,是所有电子数据的最低级别。 对于这种低级语言,没有“编译器”,而是将计算机中的电路组合和结构化,以便通过读取由高或低电状态实现的代码中的通断来“解释”它们。无论如何,这些高电平或低电平状态会导致不同的门/电路打开或关闭,通常表现不同。 在Electronic Gates 上查看更多信息。

【讨论】:

【参考方案4】:

通常,编译器作者会选择以下两种方法之一:

用其他现有语言编写整个编译器。这通常是最简单的选择。

用其他语言编写足够多的代码以获得最低限度的可用翻译器,并使用该“脚手架”作为基础,用它打算编译的语言编写适当的编译器。这更复杂,通常需要更长的时间,但本质上提供了通过在实际项目中测试语言来清除语言错误和弱点的机会。

第一个翻译代码的程序至少部分是用机器代码编写的——这些实际数字告诉 CPU 要做什么。这是最低级别,因为没有真正的机器代码“编译器”*;它只是以某种方式排列的数字,CPU 内部有电路可以在没有外部帮助的情况下处理它们。

* 有一些程序可以帮助设计解释和执行指令的硬件,但可以说它不在编译器的定义范围内。此类程序生成硬件描述(电路图等),而不是编译器输出的直接可执行文件。

【讨论】:

以上是关于编译器如何编译编译器?的主要内容,如果未能解决你的问题,请参考以下文章

c编译器解惑篇,如何早就c编译器

自己如何写编译器呢?电脑自带吗?

linux下应如何升级gcc编译器

如何构建GCC交叉编译器

如何构建GCC交叉编译器

如何使用gcc编译器