这个问题可能源于我对编译器的误解,但这里有......
人们可以在第一版K& R(第xi页)的序言中找到以下陈述:
操作系统, C编译器,基本上所有UNIX应用程序(包括用于编写本书的所有软件)都是用C语言编写的。
(我的重点)
这是我不明白的地方:C编译器在编译任何C代码之前是否必须自行编译?如果那个C编译器是用C编写的,那么编译它是否需要一个已经存在的C编译器?!
摆脱这种无限回归难题(或鸡与鸡蛋问题)的唯一方法是,用K和R指代的C编写的C编译器实际上是用已经存在的C编译器编译的。 C语言编写的C语言编译器取代了后者。
还是我完全离开了?
答案 0 :(得分:35)
它被称为Bootstrapping,引自维基百科:
如果需要语言X的编译器来获取语言X的编译器(用X语言编写),那么第一个编译器是如何编写的?解决这个鸡肉或鸡蛋问题的可能方法包括:
如果您有兴趣,here是Dennis Richie的第一个C编译器源代码。
答案 1 :(得分:9)
请参阅Wikipedia page的鸡肉和鸡蛋部分:
如果需要语言X的编译器来获取语言X的编译器(用X语言编写),那么第一个编译器是如何编写的?解决这个鸡肉或鸡蛋问题的可能方法包括:
答案 2 :(得分:6)
通常,第一个编译器是用另一种语言编写的(在这种情况下直接在PDP11汇编器中,或者在大多数“现代”语言中用C编写)。然后,第一个编译器用于编写用语言本身编写的编译器。
您可以阅读此page有关C语言历史的信息。您将看到它也与UNIX系统紧密相关。
答案 3 :(得分:5)
编译器用它编译的语言编写是完全平常的。实现这一目标的一种方法是用其他语言编写一个完整的语言L编译器,然后在L中为L编写一个新的编译器。一个更有趣的方法是为一些L的子集编写一个最小的编译器其他语言,然后使用这个最小子集来改进编译器,使其增加L的可用子集的最小化。这样,可以构建完整的编译器。