这可能是一个愚蠢的问题,但是编程语言是如何在低层次上工作的呢?如果您转到go语言GitHub页面这里,它说几乎90%的源文件是Go文件。一种编程语言怎么可能是由自己组成的,特别是90%的本身?我可以理解像Lua这样的语言是如何用C编写的,但是Go是由主要的Go文件组成的。这对我来说没有多大意义,开发人员是如何使用Go创建Go的?
发布于 2016-10-13 23:38:03
编译器或解释器和任何其他程序一样,都是程序。您可以用任何编程语言编写程序,包括Go。因此,您可以在Go中编写编译器。包括一个Go编译器。
为什么不行?
当然,为了实际使用该编译器或解释器,您还需要为该语言配备一个编译器或解释器。
例如,在Go的情况下,编译器的前几个版本都是用C编写的,因此,它们已经有了一个可以工作的Go编译器。然后,用Go编写一个Go编译器是没有问题的,因为您已经有了一个用C编写的工作Go编译器,您可以使用它来编译用Go编写的Go编译器。现在,您已经编译了用Go编写的Go编译器的版本,您可以使用它来编译用Go编写的Go编译器的未来版本。
这就是所谓的“鞋带”(源于明乔森男爵的老故事,他用自己的鞋带把自己从泥里拉了出来)。
请注意,具体而言,Go有多个不同的编译器,至少gccgo继续用C++编写;在gccgo中没有Go代码。因此,如果您丢失编译后的Go二进制文件,您可以使用gccgo重新启动引导过程。
一个编译器是用它所编译的语言编写的,并且能够自己编译,它被称为“自我托管”。自托管编译器有几个优点:
还有一些缺点:
在他的一篇文章中,Niklaus教授给出了后者的一个很好的例子:在设计Oberon语言时,他在设计语言的同时编写了编译器。他所写的系统,只有一种模糊的Fortran方言。与此同时,他意识到自己潜意识中遗漏或改变了一些功能,这些特性会使用Oberon编写程序变得更容易,因为他想不出用晦涩的Fortran方言实现这些功能的好方法。因此,他抛弃了编译器,重新审视了他的设计,并在Oberon本身启动了一个新的编译器。Oberon本来是一种系统编程语言,因此在其中编写编译器和标准库是一种自然的选择。
现在,问题是,他是如何解决自举问题的?毕竟,他是一位教授:他把编译器的一部分分发给了他的学生,用手将其翻译成Fortran。
发布于 2016-10-13 23:04:03
这是一个非常简单的问题,有一个非常深刻的答案。一个完整的解释超出了这样一个网站的范围,但我会给你足够的开始学习它。
首先,什么是编程语言?或者,更确切地说,是什么定义了编程语言?大多数专业的开发人员都认为语言是由两个主要的东西定义的:编译器/解释器和标准库。编译器列出了语言工作的语法和语义规则,标准库帮助建立语言最有用的范例和成语。
明白了,我们可以回答你的问题。快速版本是,如果编程语言能够实现基本的文件IO和数据处理,那么它就能够为一种语言实现编译器,包括它自己的语言。他们是怎么写进去的?当然,他们在Go中写了一个Go编译器!
但这不是你真正想知道的,对吧?你要问的是这个语句中固有的鸡与蛋问题:如何用一种语言编写第一个编译器,而这个语言本身还没有编译器呢?
显然不能,所以用另一种语言编写第一个编译器。这就是所谓的“引导”。不过,它甚至不需要实现整个语言;只要您能够编译一个Go编译器,它就可以完成与引导编译器所能完成的任务(即。(编译本身。)
此时,Go中有一个可工作的编译器,然后可以将新特性构建到编译器中,编译它们,并拥有一个新的和改进的编译器,等等,直到您按照设计建立了完整的语言。
发布于 2016-10-13 22:57:57
就像我可以用英语来描述和定义英语一样。
编程语言不是这样编写的。相反,它们更多地是对它们应该如何工作的描述。
编译器是实际的实现。最初我认为它是用C编写的,但是一旦你能编译语言,你就可以用这个语言创建一个编译器。
https://softwareengineering.stackexchange.com/questions/333568
复制相似问题