1. 程式人生 > >編譯原理--編譯器的自舉與移植

編譯原理--編譯器的自舉與移植

看的編譯原理,發現挺好玩的東西:自舉和移植。有個著名的問題:Mommy, where do compilers come from?要解決這個問題,首先來看看T-Diagram。可以將編譯器用一個T形圖來表示: ---------| S     T | ---   ---     | I |    ---其中,S表示Souce LanguageT表示Target LanguageI表示Implementation Language根據這個圖,可以得到兩種組合:1、 由I實現的將S翻譯成A的編譯器和將A翻譯成T的編譯器聯合起來工作,可以實現S到T的編譯。這不是很有意思的組合。 ------------------

| S     A | A     T | ---   ------   ---      | I |    | I |    ---      ---2、由I實現的將S翻譯成T的編譯器(compiler C1),由H實現的將I翻譯成K的編譯器的組合(compiler C2)。這個組合比較有意思:可以用C2去編譯C1(將其實現語言從I翻譯成K),這樣就得到由K實現的將S翻譯成T的編譯器(compiler C3): ---------                ---------| S     T |              | S     T | ---   ----------  --->   ---   ---
   | I | I     K |          | K |    -------   ---            ---          | H |           ---這便是我們所感興趣的:編譯器的編譯器。而一個程式要在某臺機器上執行時,其實現語言必須與相應的機器語言匹配。例如在x86平臺上,能執行的程式只能是x86機器語言:------------------/    Program     / //  -------------  |     X86    |  -------------  |     X86    |  -------------讓我們將T形圖和上圖聯絡起來看,以
C為例(假定已有x86C編譯器):
--------        --------       ---------/ Hello // Hello // Hello / -----------------------        ------- | C   | C    x86| x86  |  --->  | x86  | ---------    ----------        -------          |x86|                 | x86  |          ----                  -------上圖表示用C寫的Hello程式可以在C“機器上執行,然而這不是我們想要的——x86機器上執行。於是使用實現語言為x86的編譯器(其可執行程式碼)編譯形成x86語言,這樣就可以運行了。根據上面的第2條(編譯器的編譯器)以及程式的執行,我們可以得出,要想得到在M機器上執行的S語言編譯器,可以使用S語言來編寫(用M語言也可以,然而太麻煩)。但還是需要用M語言寫一個具有很小功能的S編譯器,然後用其去編譯加入了更多功能的編譯器,然後用編譯出來的更多功能的編譯器去編譯,這樣就得到了最終需要的編譯器,這便是自舉。 ---------                ---------| S     M |              | S     M | ---   ----------  --->   ---   ---   | S | S     M |          | M |    -------   ---            ---          | M |(微型S編譯器)           ---用S編寫S的編譯器還有一個好處,那就是方便移植,並且能產生交叉編譯器。假定要編譯K機器語言的S編譯器,只需要將目標語言替換成K,然後用已有的S語言編譯器來編譯: ---------           ---------| S     K |         | S     K | ---   ---------- -> ---   ---   | S | S     M |     | M |(執行在M機器上的編譯器,即交叉編譯器)    -------   ---       ---          | M |           ---有了交叉編譯器,就可以編譯在K上執行的S編譯器了: ---------           ---------| S     K |         | S     K | ---   ---------- -> ---   ---   | S | S     K |     | K |    -------   ---       ---          | M |           ---