先有雞還是先有蛋?第一個編譯器是怎麼來的~

2021-02-08 電子工程專輯

轉自: www.cnblogs.com/Chaobs/p/4510768.html

不知道你有沒有想過,某種程式語言的第一個編譯器是怎麼來的呢?這不就是「雞生蛋,蛋生雞」的問題嗎?

先說最後的結論:任何一種語言的第一個編譯器肯定是使用其他語言寫出來的

以我們嵌入式開發中經常使用的C語言為例,我們來介紹一下第一個C語言編譯器的來源。

還是讓我們回顧一下C語言歷史:1970年Tomphson和Ritchie在BCPL(一種解釋型語言)的基礎上開發了B語言,1973年又在B語言的基礎上成功開發出了現在的C語言。在C語言被用作系統程式語言之前,Tomphson也用過B語言編寫作業系統。

可見,在C語言實現以前,B語言已經可以投入實用了。因此第一個C語言編譯器的原型完全可能是用B語言或者混合B語言與PDP彙編語言編寫的。但是B語言的效率比較低,如果全部用彙編語言來編寫,不僅開發周期長、維護難度大,更可怕的是失去了高級程序設計語言必需的移植性。

所以,早期的C語言編譯器就採取了一個取巧的辦法:

先用彙編語言編寫一個C語言的一個子集的編譯器,再通過這個子集去遞推完成完整的C語言編譯器。

詳細的過程如下:

先創造一個只有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語言時,那麼你就找到N了。

下面的圖說明了這個抽象過程:

這張圖是不是有點熟悉?對了就是在將虛擬機的時候見到過,不過這裡是CVM(CLanguageVirtualMachine),每種語言都是在每個虛擬層上可以獨立實現編譯的,並且除了C語言外,每一層的輸出都將作為下一層的輸入(最後一層的輸出就是應用程式了)。

這和滾雪球是一個道理。用手(彙編語言)把一小把雪結合在一起,一點點地滾下去就形成了一個大雪球,這大概就是所謂的0生1,1生C,C生萬物吧?

那麼這種大膽的子集簡化的方法,是怎麼實現的,又有什麼理論依據呢?

先介紹一個概念,「自編譯」(Self-Compile),也就是對於某些具有明顯自舉性質的強類型(所謂強類型就是程序中的每個變量必學聲明類型後才能使用,比如C語言,相反有些腳本語言則根本沒有類型這一說法)程式語言,可以藉助它們的一個有限小子集,通過有限次數的遞推來實現對它們自身的表述,這樣的語言有C、Pascal、Ada等等,至於為什麼可以自編譯,可以參見清華大學出版社的《編譯原理》,書中實現了一個Pascal的子集的編譯器。總之,已經有CS科學家證明了,C語言理論上是可以通過上面說的CVM的方法實現完整的編譯器的,那麼實際上是怎樣做到簡化的呢?

下面是C99的關鍵字:

//共37個
auto enum restrict unsigned
break extern return void
case float short volatile
char for signed while
const goto sizeof _Bool
continue if static _Complex
default inline struct _Imaginary
do int switch double long typedef
else register union

仔細看看,其中有很多關鍵字是為了幫助編譯器進行優化的,還有一些是用來限定變量、函數的作用域、連結性或者生存周期(函數沒有)的,這些在編譯器實現的早期根本不必加上,於是可以去掉

auto,restrict,extern,volatile,const,sizeof,static,inline,register,typedef,這樣就形成了C的子集,C3語言,C3語言的關鍵字如下:

//共27個
enum unsigned break return
void case float short char
for signed while goto _Bool
continue if _Complex default
struct _Imaginary do int switch
double long else union

再想一想,發現C3中其實有很多類型和類型修飾符是沒有必要一次性都加上去的,比如三種整型,只要實現int就行了,因此進一步去掉這些關鍵詞,它們是:

unsigned,float,short,char(charisint),signed,_Bool,_Complex,_Imaginary,long,

這樣就形成了我們的C2語言,C2語言關鍵字如下:

//共18個
enum break return void
case for while goto continue
if default struct do int
switch double else union

繼續思考,即使是只有18個關鍵字的C2語言,依然有很多,高級的地方,比如基於基本數據類型的複合數據結構,另外我們的關鍵字表中是沒有寫運算符的,在C語言中的複合賦值運算符->運算符等的++,--等過於靈活的表達方式此時也可以完全刪除掉,因此可以去掉的關鍵字有:enum,struct,union,這樣我們可以得到C1語言的關鍵字:

break return void case for while
goto continue if default do int
switch double else
//共15個

接近完美了,不過最後一步手筆自然要大一點。這個時候數組和指針也要去掉了,另外C1語言其實仍然有很大的冗雜度,比如控制循環和分支的都有多種表述方法,其實都可簡化成一種,具體的來說,循環語句有while循環,do...while循環和for循環,只需要保留while循環就夠了;分支語句又有if...{},if...{}...else,if...{}...elseif...,switch,這四種形式,它們都可以通過兩個以上的if...{}來實現,因此只需要保留if,...{}就夠了。可是再一想,所謂的分支和循環不過是條件跳轉語句罷了,函數調用語句也不過是一個壓棧和跳轉語句罷了,因此只需要goto(未限制的goto)。

因此大膽去掉所有結構化關鍵字,連函數也沒有,得到的C0語言關鍵字如下:

//共5個
break voidgoto int double

這已經是簡約的極致了。

只有5個關鍵字,已經完全可以用彙編語言快速的實現了。通過逆向分析我們還原了第一個C語言編譯器的編寫過程,也感受到了前輩科學家們的智慧和勤勞!我們都不過是巨人肩膀上的灰塵罷了!

0生1,1生C,C生萬物,實在巧妙!

任何一種語言的第一個編譯器肯定是使用其他語言寫出來的。那就有一個問題了:第一種語言的第一個編譯器是怎麼來的呢?哈哈!

1.7位專家匯集| 不可不聽的線上嵌入式技術講座在這裡!

2.樹莓派 4:全新的背後,依然是優秀的表現嗎?

3.對國內半導體代工廠「保留無限追溯」,裡面有誤讀!

4.既想馬兒一直跑又想馬兒不吃草,這款Wi-Fi 晶片幫你實現了!

5.單片機裡面的CPU使用率是什麼鬼?

6.學Linux驅動:應先了解總線驅動模型!

免責聲明:本文系網絡轉載,版權歸原作者所有。如涉及作品版權問題,請與我們聯繫,我們將根據您提供的版權證明材料確認版權並支付稿酬或者刪除內容。



相關焦點

  • 先有C語言還是先有的編譯器?這是一個雞與蛋的問題
    可是問題來了,不知道你有沒有想過,大家都用C語言或基於C語言的語言來寫編譯器,那麼世界上第一個C語言編譯器又是怎麼編寫的呢?這不是一個「雞和蛋」的問題…… 因此第一個C語言編譯器的原型完全可能是用B語言或者混合B語言與PDP彙編語言編寫的。
  • 先有雞還是先有蛋?歷史人物早有答案?
    先有雞還是先有蛋,這是個哲學一樣的問題。蛋是雞下的,雞是蛋孵的。沒有雞就沒有蛋,沒有蛋就沒有雞,至少很多人陷入了這樣一個矛盾的怪圈。 那麼,究竟是先有雞還是先有蛋呢?
  • 科學分析先有雞還是先有蛋
    我們上小學的時候就聽過先有雞還是先有蛋這個問題但始終沒有形成統一意見各位認為是先有雞還是先有蛋呢?在分析之前我先拋出我的觀點,我認為是先有「雞」先別急著噴我,看圖說話在很久很久以前,地球上出現了一些單細胞生物至於有機物是怎麼變成細胞的我也不知道總之一定是出現了一個細胞
  • 科學菌:先有雞還是先有蛋,答案是什麼?
    先有雞,還是先有蛋?這個問題可謂是大大的悖論,無論是誰都難以給出一個令人信服的答案。但這並不代表它沒有答案,在現如今,我們可以從現有的科學理論中找到這個問題的答案。
  • 不要再問先有雞還是先有蛋了
    昨天在高中的同學群裡閒聊,老同學們問我說:「大連,你是學生物的,那你給大家說說到底是先有的雞還是先有蛋?」在生活中,常識讓大家知道雞是蛋孵化出來的,而蛋又是雞生出來的。於是就自己陷入了一個不可破解的謎團,甚至有時會產生一種好似自己能質疑世界的錯覺。
  • 先有雞還是先有蛋?看看兩個最明智的回答,嘆為觀止
    先有雞還是先有蛋?這是千百年來人們茶餘飯後喜歡討論的一個問題。這也確實是一個問題,而且一直困擾著我們,怎麼回答都好像在兜圈子,兜不出來。先看看大哲學家老老實實的回答。有一天,古希臘一個年輕人自以為自己比大哲學家蘇格拉底還聰明,匆匆地找蘇格拉底爭辯問題,要蘇格拉底先向他發問。蘇格拉底問年輕人:「世上先有雞還是先有蛋?」
  • 先有雞還是先有蛋?這個問題有答案嗎?答案是什麼?
    先有雞還是先有蛋?這個問題有答案嗎?這個問題,是一個很有名的哲學問題,真的是千古難題。不知道這個問題難住了多少人?也不知道這個問題是什麼時候出現的?根據一些資料分析,「先有雞還是先有蛋」這個問題應該有幾千年的歷史了。思考,是人類進步的一個重要途徑。善於思考的人類,喜歡思考人生,分析問題。思考「先有雞還是先有蛋」這樣的問題,是非常有意義的!那麼,先有雞還是先有蛋?這個問題,有答案嗎?當然有。
  • 先有雞還是先有蛋?千古謎題科學家終於給出了解答!
    先有雞還是先有蛋?千古謎題科學家終於給出了解答!先不說世界上的一些十大未解之謎,像外星人法老王這樣的問題了,就像是我們現實生活中最簡單的一個問題,到底是先有蛋還是先有雞這一問題,到現在都沒有得到一個明確的回覆,這個問題究竟該怎樣定論呢?關於這個問題似乎已經進入了一個死循環,如果先有雞,那麼雞是怎麼來的?雞是蛋生出來的,那麼蛋是怎麼來的?先有雞還是先有蛋?千古謎題科學家終於給出了解答!
  • 世界上先有雞還是先有蛋?
    傳說,諸葛亮赴東吳商討抗曹大計時,周瑜問諸葛亮「先有雞還是先有蛋」。諸葛亮回答:「雞蛋,雞蛋,先雞而後蛋,當然先有雞了。」周瑜不認,說這是「饒舌之言,算不得答案」。諸葛亮於是就解釋說:「雞蛋分兩種,一種是能孵化出雞仔的蛋,一種是孵不出雞仔的蛋,叫謊蛋,又稱笨蛋,歇後語二十一天不竄尖——笨蛋,即此謂也,倘若世界上第一個蛋正好是笨蛋的話,雞族豈不是絕後了嗎? 」周瑜竟無言以對。
  • 先有雞還是先有蛋?這裡有了答案,你相信嗎?
    到底先有雞還是先有蛋,現在也只能是分析,誰也不能確定下來,這個問題看著簡單,實際也是各說各有理,如果說先有雞,那雞怎麼孵化出來的呢?說先有蛋吧,蛋也是雞生的。一個矛盾的問題。第一種結論先有雞,據說英國的科學家對這個問題得到了答案,就是先有雞後有蛋,因為他們發現一種物質,是一種能夠催化蛋殼形成的蛋白質,這種蛋白質只有雞的卵巢中才有。就是說沒有雞的話也就沒有這種蛋白質,那麼是根本不可能形成蛋殼的,從而形成雞蛋保護小雞被孵化,所以他們的結論是先有雞後有蛋。
  • 辨別:先有雞?還是先有蛋?
    如果筆者問您:先有雞,還是先有蛋?當筆者問及許多學生這個問題時,無論是小學生、中學生、大學生,還是研究生,他們或認為這是一個錯誤的邏輯循環而不可解或認為「先有雞,後有蛋」或認為「先有蛋,後有雞」當筆者問持後一種答案的學生為什麼「先有蛋」時,他們大多數都不能給出科學合理的解釋。
  • 雞生蛋、蛋生雞,先有雞還是先有蛋?別打架!來看答案
    到底是先有的雞還是先有的蛋?為何這個話題可以困擾人類數千年之久?即便現在已經有了正面的回覆,但還是有無數學者在爭論這一話題,難道真像真有那麼複雜嗎?如果你也對此感到疑惑,記得一定要看到最後,因為這裡將會有你想要的答案,大家好,我是小橙,今天跟大家聊雞蛋。
  • 生物進化史:先有蛋還是先有雞,有了答案!
    ,有網友評論說先有蛋還是先有雞,這個其實是一個歷史性的問題,很多人都對此進行了分析,也並沒有一個完整的標準答案或者答案並不能讓人信服,那麼我們今天從生物進化史來研究這個先有蛋還是先有雞的問題進行探討。在各個生物考古中發現得知恐龍是一種卵生動物,也就是恐龍的生育是通過下蛋繁殖的,全球各地均有發現恐龍蛋的化石,在發現恐龍蛋後,也就是說先有了恐龍後再生育恐龍蛋,那麼我們今天的話題不是先有雞還是先有蛋嗎?這點其實我們後面要提到,我們之前的文章中介紹雞和鳥類是恐龍進化而來,由此斷定雞是先存在的生物,從而又生了蛋,這樣說大家不一定會信服。
  • 先有雞還是先有蛋,哲學家和科學家給出相同的答案
    先有雞還是先有蛋問題的提出 先有雞還是先有蛋,拿這個問題去問哲學家,肯定得不出什麼有建設性的回答,可能哲學家會給你分析好多,可依然沒有證據能夠充分說明,但是好歹有個答案。
  • 究竟是先有雞還是先有蛋?
    像我這種有辯證論述臭毛病的,就忍不住想用科普的角度出一個定論。結論:先有雞。其實這個問題的答案很簡單,只不過大多數人不喜歡去思考罷了。不過雞作為一個物種出現的同時,這個物種的繁殖方式就確定了。也就是說,用蛋來繁殖在第一隻雞出現的同時已經確定了。我們可以理解為先雞後蛋,但是蛋並不落後於雞。有點拗口,且聽下面分解。
  • 先有雞,還是先有蛋?英國教授給出了答案
    科學研究,雖然聽起來十分高大上,但是有一些課題聽起來就十分接地氣了,甚至有的課題會讓人感覺到十分得無聊,比如在學界,一直有著「先有雞後有蛋」還是「先有蛋後有雞」的討論,甚至許多科學家們為此進行了長年累月的科學研究,就只是為了證明到底雞和蛋哪個最先出來。
  • 先有雞還是先有蛋 這個問題終於有科學答案了
    先有雞還是先有蛋 這個問題終於有科學答案了時間:2019-11-30 22:31   來源:今日頭條   責任編輯:毛青青 川北在線核心提示:原標題:先有雞還是先有蛋 這個問題終於有科學答案了 一直以來先有雞還是先有蛋,都是在我們朋友圈直接被廣泛流傳的一個腦筋急轉彎問題,而這是一個沒有標準答案的問題,相信很多人在小時候也被自己的家人刁難
  • 先有雞還是先有蛋什麼梗?先有雞還是先有蛋答案是什麼?
    南古所 供圖中新網南京11月28日電(楊顏慈)中國科學院南京地質古生物研究所28日發布消息,該所殷宗軍副研究員和朱茂炎研究員,與英國布裡斯託大學、瑞典自然歷史博物館以及瑞士光源的同行合作,在中國貴州甕安生物群——一個距今6.1億年的特異埋藏化石庫中找到了一類名叫「籠脊球」的化石,為回答「先有雞還是先有蛋」提供了新思路。
  • 萬元懸賞:尋找到底先有雞還是先有蛋的最佳解答
    到底先有雞還是先有蛋?這個問題不僅困擾大眾,而且難倒不少世界知名的哲學家和生物學家。今天我也來湊熱鬧解答一下這個世界級難題,同時我還準備了一萬元賞金,誰解答得比我更好,這一萬元賞金就歸誰。遊戲規則只有一條:一旦發現誰的解答觀點比我有創意且更有說服力誰就是最佳解答,那麼誰就能拿到這一萬元賞金,不然等於默認我的解答觀點是世界最佳。
  • 地球上究竟是先有雞還是先有蛋?中國科學家找到了答案,真了不起
    在科學界一直流傳一個古老而又有趣的問題:這個世界上究竟是先有雞還是先有蛋,有的人認為世界應該先有雞,因為雞蛋是雞生出來的,沒有雞生產哪裡存在蛋;而有的人卻認為世界應該先有蛋,因為雞是蛋孵化出來的,沒有蛋哪裡有雞這種生物;好像這兩種結論都說得很有道理,就是因為兩種答案都有道理,因此這個問題也就沒有了答案