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語言理論上是能夠經過上面的方法實現完整的編譯器的。

相關文章
相關標籤/搜索