可能重复:
How can a language's compiler be written in that language?
implementing a compiler in “itself”
我正在查看Rubinius,这是一个使用Ruby编写的编译器编译为字节码的Ruby实现。我无法理解这一点。你如何编写语言本身的语言编译器?似乎只是文本没有任何东西可以将它编译成可执行文件,然后可以编译用Ruby编写的未来代码。我只是输入那句话感到困惑。任何人都可以帮忙解释一下吗?
答案 0 :(得分:17)
简化:首先使用不同的语言为编译器编写编译器。然后,编译编译器,瞧!
所以,你需要某种已经有编译器的语言 - 但是由于有很多这样的语言,你可以编写Ruby编译器编译器(!),例如在C中,然后编译Ruby编译器,然后编译Ruby程序,甚至编译自己的其他版本。
当然,原始编译器是用机器代码编写的,编译后的编译器用于汇编,后者编译编译器例如编译器。 C或Fortran,编译编译器......几乎所有东西。 Iterative development in action.
这个过程被称为bootstrapping - 可能是以男爵蒙克豪森的故事命名的,在这个故事中,他通过自己的引导将自己从沼泽中拉出来:)
答案 1 :(得分:3)
关于编译器的引导,值得一读的是这个非常聪明的黑客。
答案 2 :(得分:2)
我只是在阅读那句话时感到困惑。
将编译器视为转换器可能会有所帮助,通常会调用编译器。它的目的是获取人类可以读取的源代码并将其转换为计算机可以读取的二进制代码。在Rubinius的情况下,它读取的代码恰好是Ruby代码,它转换成代码的代码是机器代码(实际上LLVM机器代码本身进一步编译成Intel机器代码,但这只是一个背景细节) 。 Rubinius本身可以用任何编程语言编写。它碰巧是用它编写的同一种语言编写的。
当然,你需要一些东西来运行Rubinius,这很可能是一个常规的Ruby解释器。但请注意,一旦您能够在解释器上运行Rubinius,您就可以将其自己的源代码传递给它,并且它将创建并运行自身的编译版本。这被称为引导,从旧的短语,“通过引导拉自己”。
最后一点:Ruby程序无法调用任意机器代码。 Rubinius的那部分实际上是用C ++编写的。
答案 3 :(得分:0)
可以按以下顺序进行:
玩得开心! :)
答案 4 :(得分:0)
编译器只是将源代码转换为可执行文件的东西。所以写它的内容并不重要 - 它可以是它编译的语言,也可以是任何其他足够强大的语言。
当你为同一种语言编写的平台语言编写器时,很有趣,它还没有针对你的实现语言的编译器。你在这里的选择是在另一个你有编译器的平台上编译,或用另一种语言编写编译器,然后用它来编译“真正的”编译器。
答案 5 :(得分:0)
这是一个两步过程:
因为有人已经编写过Ruby编译器(Matz),所以你“只”必须做第二部分。说起来容易做起来难。
答案 6 :(得分:0)
到目前为止,所有答案都解释了如何使用不同的编译器来引导编译器。但是,还有另一种选择:手动编译编译器。没有理由为什么编译器必须由机器执行,它也可以由人执行。