C语言编译器为何可以用C语言编写?

不知道你们有没有想过一个问题:C语言编译器为何可以用C语言编写?python

所谓C语言编译器,就是把编程获得的文件,好比.c,.h的文件,进行读取,并对内容进行分析,按照C语言的规则,将其转换成cpu能够执行的二进制文件。程序员

 
在学习C/C++或者想要学习C/C++能够加入咱们的学习交流QQ群: 954607083 ,领取学习资料

其本质在于对文件的读入,分析,及处理。这些操做,C语言都是能够实现的。编程

因此用C语言来作C语言的编译器是彻底可行的。编程语言

可是,历史上的第一个C语言编译器,确定不是C语言写的,由于在没有编译器时,没法把C语言转换成可执行文件。只要有了初版其它语言的编译器,就能够用C语言写编译器了。学习

 
在学习C/C++或者想要学习C/C++能够加入咱们的学习交流QQ群: 954607083 ,领取学习资料

那么世界上第一个C语言编译器又是怎么编写的呢?操作系统

仍是让咱们回顾一下C语言历史:设计

1970年Tomphson和Ritchie在BCPL(一种解释型语言)的基础上开发了B语言,3d

1973年又在B语言的基础上成功开发出了如今的C语言。orm

在C语言被用做系统编程语言以前,Tomphson已经使用B语言编写过操做系统。可见在C语言实现之前,B语言已经能够投使用了。开发

 
在学习C/C++或者想要学习C/C++能够加入咱们的学习交流QQ群: 954607083 ,领取学习资料

所以第一个C语言编译器的原型彻底多是用B语言或者混合B语言与PDP汇编语言编写的。

事实上,B语言的执行效率比较低,可是若是所有用汇编语言来编写,不只工做量巨大,并且汇编语言的可读性极差,很容易就会出错!

上一张图你们感觉一下这巨大的差异!!!

 
在学习C/C++或者想要学习C/C++能够加入咱们的学习交流QQ群: 954607083 ,领取学习资料

为了克服这个困难,早期的C语言编译器就采起了一个取巧的办法:先用汇编语言编写一个C语言的一个子集的编译器,再经过这个子集去递推完成完整的C语言编译器。

大体过程以下:

 
在学习C/C++或者想要学习C/C++能够加入咱们的学习交流QQ群: 954607083 ,领取学习资料

先创造一个只有C语言最基本功能的子集,记做C0语言,C0语言已经足够简单了,能够直接用汇编语言编写出C0的编译器。

依靠C0已有的功能,设计比C0复杂,但仍然不完整的C语言的又一个子集C1语言,其中C0属于C1,C1属于C,用C0开发出C1语言的编译器。

在C1的基础上设计C语言的又一个子集C2语言,C2语言比C1复杂,可是仍然不是完整的C语言,开发出C2语言的编译器……如此直到CN,CN已经足够强大了,这时候就足够开发出完整的C语言编译器的实现了。

至于这里的N是多少,这取决于你的目标语言(这里是C语言)的复杂程度和程序员的编程能力。

 
在学习C/C++或者想要学习C/C++能够加入咱们的学习交流QQ群: 954607083 ,领取学习资料

那么这种大胆的子集简化的方法,又有什么理论依据呢?

先介绍一个概念,“自编译”Self-Compile。

对于某些具备明显自举(不知道哪一个鬼才起的名字)性质的强类型编程语言

能够借助它们的一个有限小子集

经过有限次数的递推来实现对它们自身的表述

(所谓强类型就是程序中的每一个变量必须声明类型后才能使用,好比C语言,相反有些脚本语言则根本没有类型这一说法,好比python。)

知足自编译这样的语言有C、Pascal、Ada等等,至于为何能够自编译,能够参见清华大学出版社的《编译原理》,书中实现了一个Pascal的子集的编译器。

 
在学习C/C++或者想要学习C/C++能够加入咱们的学习交流QQ群: 954607083 ,领取学习资料

总之,已经有计算机科学家证实了,C语言理论上是能够经过上面的方法实现完整的编译器的。

相关文章
相关标签/搜索