关于编译器的自举实现(关于如何实现一门闭环语言)

从一个既对也不对的观点讲起:

首先说一个流传观点,Java的底层源码是用C语言和C++去是实现的,这种说法既对也不对,实际在OpenJDK源码中,其实JIT是由C语言去实现的,其中的核心比如关于gc的代码是由C++去实现的

可是在现在的Java可能不是由C或者C++去实现的,可能是自己去实现的

这个自己实现自己仿佛不符合正常的认知,好像一个蛋生鸡或者鸡生蛋的问题

这里就要提到一个很关键的概念,就是自举:

编译器自举指用本编译器被编译的语言来编写本编译器。编译器自举一般都是编译器开发的一个里程碑事件。 编译器自举意味着被编译的语言荣升成自编译语言,而且编译器拥有自举能力对实现语言的语法语义本身没有限制

JAVA其实一门已经实现过自举的语言 ,Oracle用java自己实现了一个把Java字节码编译成机器码的编译器,这个编译器就是Graal,作为一个成熟的现代编译器,Graal的能力基本可以和Clang,GCC等现代顶级的编译器互相竞争,它与物理硬件的指令集一样,做到了只与机器特性相关而不与某种高级语言特性相关

关于如何创造一门自举编程语言的途径:

1.创造一门图灵完备(Turing Complete)的语言X

(关于图灵完备:图灵机(Turing Machine)是图灵在1936年发表的 "On Computable Numbers, with an Application to the Entscheidungsproblem"(《论可计算数及其在判定性问题上的应用》)中提出的数学模型。既然是数学模型,它就并非一个实体概念,而是架空的一个想法。在文章中图灵描述了它是什么,并且证明了,只要图灵机可以被实现,就可以用来解决任何可计算问题)

2,用其他语言(C,C++或者其他)把想创造的编译器写出来,这个编译器可以实现编译X的过程,就把这个编译器称为称为A吧

3.用自己创建的语言去实现编译器代码,把它叫为B,然后用A去编译B

4.这时候B已经可以拿来去编译X了,完善X的代码得到X1,再次拿B编译X1,得到B1

5.完善X1得到X2,拿B1编译X2得到B2

6.重复以上步骤,就会发现自己可以编译自己了

拿常见的C++语言去举例子:

使用C++98写支持C++11的C++编译器,而等待时机成熟后,就又可以使用C++11来写支持C++14的C++编译器,随后可以使用C++14来写支持C++20的C++编译器,然后自己迭代出自己的下一代

从根本上讲:

可执行文件A和B本身和编程语言没有任何关系,因为底层都被翻译成机器码了,编译器干的就是把高级语言最终翻译成机器码的过程,其实整个exe执行的过程本质上执行的就是机器码,也就是说编译器本身已经和写它的底层语言其实没有直接关系了

猜你喜欢

转载自blog.csdn.net/qq_36653924/article/details/128655595