引导编译器涉及到产生一个自我编译的编译器,也就是说,我们使用语言A编写一个编译器,为目标机器B产生代码,并且还能自我编译。
目录:
- 简介
- 符号
- 总结
- 参考文献
引言
正如我们在以前的文章中所看到的,我们为Kaleidoscope编程语言建立了一个编译器,并支持许多编程语言的功能,JIT编译,以及更多。我们使用一种高级编程语言--*C++*来完成这一切。
我们的另一个选择是使用一种在编译器运行的目标机器上已经有的编程语言。
另一种常见的情况是,我们有一个新的处理器,但还没有编译器。
尽管这个事实,我们想要一个编译器,不仅针对这个特定的处理器,还能在上面运行。我们想为语言A编写一个编译器,以语言B为目标,用语言B编写。
一个明显的方法是用B语言编写一个编译器,如果B是机器码,那么编写任何非琐碎的编译器都是一个困难的任务,相反,传统的方法是使用一个被称为引导的过程。
这个想法如下,我们用A语言编写一个编译器,让它自己编译。这样做的结果是用B语言写出一个从A到B
的编译器。
以上似乎是鸡和蛋的悖论,然而,我们将讨论如何解决这个悖论。
符号化
我们使用\H.Bratman\设计的符号,它被称为Bratman图。
我们有以下的符号,它表示一个用C编程语言编写的编译器,编译一种语言A和目标语言B

为了能够使用这个编译器,它必须站在一个坚实的基础上,也就是能够执行用C编程语言编写的程序的东西。
它可以是一台能够作为机器代码执行C代码的机器,也可以是运行在另一台机器或解释器上的C解释器。
几个解释器可以放在彼此的上面,但在这一切的底部,我们需要一个真正的机器。
一个用D语言编写的解释器,正在解释C语言,用下图表示:

一台直接执行D语言的机器用下图来表示:

上图中,尖尖的底部表示机器不需要站在任何东西上,它本身就是一个基础,其他东西都站在上面。
为了表示一个用D语言编写的未指定的程序,我们使用下图:

这些数字可以组合起来表示程序的执行,例如,在机器D上运行一个程序的结果是这样的:

另外,不是说语言必须匹配,程序应该用机器可以理解的语言编写:
我们插入一个解释器,如下:

另外,注意在这种情况下语言也必须匹配,解释器只能解释用解释器可以解释的语言编写的程序。
我们可以运行一个编译器,并使用下面的方法来编译一个程序:

输入显示在左边,输出显示在右边。
语言在每个连接处都是匹配的,源程序和目标程序没有站在任何东西上,因为它们在上图中没有被执行。
我们插入和解释器,如下所示:

总结
在bootstrapping中,我们的目标是使用语言A编写一个编译器,为目标机器B产生代码,同时还能自我编译。