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