Ken 說,,C 編譯器是用 C 語言編的,。
以下有一些是我自己的猜想: 這并不是說第一個 【C 編譯器二進制文件】 就能編譯完整的 C 程序。 C 編譯器一開始處于創(chuàng)世紀的時代,,非常簡單,, 我猜想肯定是機器語言寫的,,但是不用很復雜, 只需要最最基本的一點點就夠了,。 之后 C 編譯器開始用 C 語言寫了,,寫完后用 最初的編譯器編譯,這樣新版本的 C 編譯器誕生了,。 然后再重新添加新的功能,,修改編譯器源程序, 再用上一個版本的編譯器編譯最新版本的編譯器源程序,, 編譯后的二進制文件替換上一個版本的編譯器二進制文件,。 就這樣,C 編譯器不斷得訓練自己,,使自己的 C 語言 知識越來越豐富,,到最后,它完全實現(xiàn)了 C 語言規(guī)范,, 可以正式發(fā)布給大家使用了,。 跟人不一樣,人學了一點新的語言知識后,,很可能 會忘掉,,然后再學,反復幾下,,可能就記得久一點,, C 編譯器不同,只要告訴它一次,,它就永遠記住了,。 下面舉個例子來說明一下 Ritchie, Ken 他們是如何 訓練編譯器的。 C 語言中的字符常量及字符串中可以用反斜杠 \ 字符 來轉義,,比如 \\ 表示 \,,\n 表示一個換行符, \t 表示 按一個Tab鍵產生的制表符。 在引入這個轉義機制以前,,C 編譯器認為 char *a="\\"; 這個寫法表示由2個反斜杠組成的字符串,。 現(xiàn)在改寫編譯器的源代碼為: ... c = next(); if(c != '\') return c; c = next(); if(c == '\') return '\'; ... 用老的編譯器重新編譯修改后的源代碼,生成后的編譯器 現(xiàn)在就有能力識別 \ 是轉義符了,。然后用新編譯器編譯時,, char *a="\\"; 就是表示由1個反斜杠組成的字符串了。 這個時候,,新的編譯器反倒不能正確編譯它自身的源碼了,, 因為 '\' 不再表示單個 \ 字符了,c = '\' 就非法了。 所以這時候就要寫成 ... c = next(); if(c != '\\') return c; c = next(); if(c == '\') return '\\'; ... 然后再重新編譯一遍,,雖然沒有增加新的能力,,但是源代碼 的表現(xiàn)方式已經徹底改變了。 之后,,要增加新的轉義項目,,比如把 \n 轉義為一個換行符。 不是簡單地添加一句 if(c == 'n') return '\n'; 就可以的,,因為編譯器現(xiàn)在還不知道 \n 的意思,,所以你 寫成 '\n' 并不能轉義為換行符。 所以現(xiàn)在只能寫成 if(c == 'n') return 10; 因為換行符的 ASCII 碼是10,。這樣編譯器能夠接收了,。編譯完 生成新的編譯器后,再修改原來的編譯器代碼為: if(c == 'n') return '\n'; 現(xiàn)在編譯器就懂了,,然后重新編譯它自身的源程序,。 類似地,要增加別的轉義項目,,也要如此這般地訓練編譯器,。 |
|