我和朋友正在讨论一个问题,认为这可能是询问此问题的最佳场所?
新语言是如何产生的?这个新语言NEW必须用某种旧语言OLD来编写(例如C++在初始阶段是用C语言编写的),或者它是如何创建的?同时,如果没有针对该语言NEW的编译器,那么该语言NEW如何能够自行运行?因此,必须有一个编译器。那么谁会为其编写编译器呢?
所以,所有这些是如何协同工作的,新语言及其编译器,与其旧基础语言的关系是什么?
我和朋友正在讨论一个问题,认为这可能是询问此问题的最佳场所?
新语言是如何产生的?这个新语言NEW必须用某种旧语言OLD来编写(例如C++在初始阶段是用C语言编写的),或者它是如何创建的?同时,如果没有针对该语言NEW的编译器,那么该语言NEW如何能够自行运行?因此,必须有一个编译器。那么谁会为其编写编译器呢?
所以,所有这些是如何协同工作的,新语言及其编译器,与其旧基础语言的关系是什么?
好问题!
有时,新语言的编译器是用旧语言编写的。
如果新语言N的编译器是用N编写的,则有许多策略,所有这些策略都涉及找到一种在没有编译器的情况下运行语言N程序的方法。
为语言N编写一个解释器,比如用C(真正的选择语言)编写解释器,然后使用解释器来解释编译器编译自身。
为N编写一个非常糟糕的编译器,比如用C编写,然后使用该编译器来编译编译器的第一个版本。
手工将编译器的第一个版本编译成汇编代码或C代码。
我最喜欢的是策略#1,但它们都有效。
如果您希望深入了解此问题的解决方案,请查看安德鲁·阿普尔(Andrew Appel)的短篇论文 Axiomatic Bootstrapping: A Guide for Compiler Hackers,可从普林斯顿网站免费获取。该论文非常数学化,但在相关工作部分,您将找到参考旧论文的引用,其中包括使用 T-diagrams 显示引导过程的论文,这些论文让许多人感到非常直观。
一种编程语言通常只是一个规范。任何一种语言都可以编写成使用你选择的语言的编译器或解释器。首先,我们使用机器代码编写了编译器或解释器。然后出现了汇编语言,然后是其他像C这样的语言。自那时起,C(和C ++)一直是实现一种语言的流行选择。但是C和C ++并不是唯一的选择。
值得指出的是,通常可以使用专用语言(或语言)(如yacc和lex)来实现语言。这些是特定领域的语言,专门设计用于根据规范轻松创建编译器。这消除了手动编写许多可以轻松由计算机生成的代码的乏味。您将规范通过这些工具运行,然后生成实现您的语言的代码。Yacc代表Yet Another Compiler-Compiler。它编译编译器的规范并生成编译器。
其他作者建议,一旦语言足够稳健,编译器就可以被移植到其自身,但这并非必要。许多语言在十年或更久以前用C编写,并且今天仍在C中实现。