在閱讀 編譯原理相關(guān)書籍時(shí),意識(shí)到編譯器設(shè)計(jì)本質(zhì)上是語言翻譯的簡(jiǎn)化問題; 我們把高級(jí)語言書寫的代碼,通過編譯器 + 解釋器 的過程 變成計(jì)算機(jī)可以理解的機(jī)器碼;就是相當(dāng)于把一段文字翻譯給一個(gè)外國人聽;當(dāng)然編譯器的翻譯工作要比自然翻譯的過程簡(jiǎn)單很多;但是設(shè)計(jì)思想可以借鑒;
現(xiàn)在選取一個(gè)角度,來思考一些問題;
一個(gè)由語言L編寫的,將語言X程序文件翻譯成語言Y程序文件的翻譯程序稱為編譯器,記作CLXY
編譯器應(yīng)該選擇什么語言來實(shí)現(xiàn)呢?假設(shè)沒有任何前人的工作,那必須用匯編寫一套編譯器去編譯高級(jí)語言,編譯器毫無疑問是一項(xiàng)復(fù)雜的工作的,用匯編這種低級(jí)語言去直接實(shí)現(xiàn)它,基本上是一個(gè)難到無法發(fā)成的工作;這是一個(gè)核心問題,匯編實(shí)現(xiàn)編譯器這種復(fù)雜軟件難度太大!
先放下上面的問題稍后再說,假設(shè)已經(jīng)歷經(jīng)千辛萬苦實(shí)現(xiàn)了一個(gè) L --> A的編譯器CALA;我們來思考下面2個(gè)問題;
-
當(dāng)已經(jīng)存在語言X實(shí)現(xiàn)的編譯器后,可以用該語言X實(shí)現(xiàn)任何其他語言的編譯器for 任何計(jì)算機(jī);
- Case 1 : 不同語言編譯問題
我們應(yīng)該如何設(shè)計(jì)一個(gè)新的編譯器, 它可以從另一個(gè)高級(jí)語言 X --> A 計(jì)做 C?XA
方案: 用L寫一個(gè) 具有 X --> A編譯功能編譯器CLXA, 然后用CALA編譯CLXA; - Case 2: 同一語言在不同計(jì)算機(jī)上移植問題;
我們應(yīng)該如何設(shè)計(jì)一個(gè)新的編譯器, 它可以從 L --> B 計(jì)做C?LB;
方案: CALA的編譯器上用L語言生成可被B識(shí)別的機(jī)器碼字節(jié)碼文件T;將T復(fù)制到B上執(zhí)行,解決了移植問題;
方案: 用L寫一個(gè) 具有 X --> B編譯功能編譯器CLXB, 然后用CALA編譯CLXB;
- Case 1 : 不同語言編譯問題
現(xiàn)在再回答一開始的問題,如何實(shí)現(xiàn)一個(gè)編譯器L-->A,直接用匯編簡(jiǎn)直難到不可能;
其實(shí)Case 1已經(jīng)給出了這個(gè)問題的一個(gè)方案;遞歸分解;
-
編譯器自展
將語言拆分成L1...Ln個(gè)層次(Ln-1 屬于Ln),首先實(shí)現(xiàn)最底層核心的L1部分的編譯器, 然后在用L1語言編譯器實(shí)現(xiàn)L2的功能....以此遞歸下去,然后實(shí)現(xiàn)整個(gè)語言; -
編譯器自舉
編譯器自舉的概念是是用高級(jí)語言L是用L語言寫的編譯器編譯自身,計(jì)做CLL?, ?表示它是可以移植的;
這個(gè)目標(biāo)似乎聽起來不太可能(雞生蛋,蛋生雞),但是現(xiàn)在一些語言的編譯器比如GOLANG它得編譯器就是自舉;但現(xiàn)在簡(jiǎn)要說明一下步驟:
首先理解我們所說的編譯器C是一個(gè)可執(zhí)行文件是比如windows下的exe文件,它本身與語言無關(guān),OS也不關(guān)注源文件是什么; java中的jar并不是可執(zhí)行文件;
假設(shè)發(fā)明了一個(gè)新的語言X, 我們要設(shè)計(jì)一個(gè)用X語言書寫的,并可以編譯X語言文件的編譯器C for 計(jì)算機(jī)A 做CXXA;- 用一個(gè)已知語言J的編譯器做一個(gè)可以編譯將X語言編譯為A的編譯器,計(jì)做CJXA;
- 用X語言實(shí)現(xiàn)功能與CJXA, 功能一摸一樣的編譯器即為CXXA;然后用編譯器CJXA 去編譯生成編譯器;
- 在基于自展思想,完全可以用CXXA 取代CJXA,即使是未來需要增強(qiáng)修改編譯器本身的功能;
使用編譯器自舉的優(yōu)勢(shì)就不深入分析,畢竟未來用到的機(jī)會(huì)不多;我們的核心是要理解這種思想;
接下來在進(jìn)一步思考
- 關(guān)于Java的編譯器是不是自舉問題,應(yīng)該不是;我目前還不是特別理解自舉實(shí)現(xiàn)的好處,只是覺得自舉這個(gè)思想很有趣;此外Java號(hào)稱與與平臺(tái)無關(guān)(這里的平臺(tái)即包括執(zhí)行的OS平臺(tái),也包括語言平臺(tái)(Java虛擬機(jī)不僅僅只支持java語言),如果是自舉,到底用具體什么語言去自舉呢?
- 如前所述當(dāng)已經(jīng)存在語言X實(shí)現(xiàn)的編譯器后,可以用該語言X實(shí)現(xiàn)任何其他語言的編譯器for 任何計(jì)算機(jī)(其實(shí)換句話說,只要你掌握了一門語言,那么通過學(xué)習(xí)你就可以掌握任何一門語言更容易理解); 如果我們把這個(gè)語言X在Java語境中就理解成Class文件(字節(jié)碼),也就不難理解Java跨平臺(tái)特性,也并非難到無法實(shí)現(xiàn);在自然語義分析中,這個(gè)語言X就可以理解成某種中間語言,據(jù)我所知,google翻譯就是采用這種中間語言的方式來處理不同語言間的翻譯;即在概念上,字節(jié)碼(java) == 中間語言(自然語言的互相翻譯);所以它們的好壞,很大程度上就取決于這個(gè)中間層的規(guī)范以及設(shè)計(jì)了;