1. 程式人生 > >預編譯元件完工的一點歸納總結

預編譯元件完工的一點歸納總結

原文連結:http://blog.csdn.net/sonicling/article/details/1435813


剛剛完成了C++編譯器預編譯元件。只能說大致完成了,有一點還沒有達到C++標準所要求的,那就是條件預編譯,也即#if directive的comparing expression。根據C++文件,#if 後面應該是一個整型,或者可以看作整型的表示式,我的理解是除了整數外只有bool型別才能看作整型。因此#if後面可以跟數字、比較、defined表示式。但是如果比較兩個字串呢?或者一個是字串,另外一個是整數?而且根據文件,形如“(0)”的巨集定義應該看作“0”,這一點比較麻煩,需要進行深層次的語法分析。然而首先完成的是預編譯元件,語法分析還沒有開始寫。因此等到語法分析元件完工後再回過頭來完善。
          還有一個問題是效率問題。用一個C檔案測試,該檔案包含了<algorithm>。預編譯比較慢。估計是debug的緣故,大概需要2秒,release一定快一些。但是這僅僅是預處理一個檔案。如果有大量的檔案就需要更多的時間。效率瓶頸估計出在對token的封裝上,也就是詞法分析器元件。我將詞法分析器用模板封裝為了token,在其上過載++操作以完成get_next_token的功能。而token使用的iterator不是char*,而是另外自定義的filebuffer_iterator,原因就是檔案在記憶體中可能是分散的,不連續的,使用char*將不利於對整個檔案的遍歷。而關鍵就是filebuffer_iterator的效率。每次token++都會呼叫iterator++多次,因此iterator的效率有待加強。當然要改為使用char*作為iterator也很容易,因為token和filebuffer_iterator沒有依賴關係,直接替換模板引數即可。
          接下來就要寫語法分析器元件。該元件的目的是將預編譯的輸出檔案轉換為語法樹,優化則是之後的事情。目前有兩條途徑可以供我選擇:1、使用硬編碼,直接在草稿上分析出FIRST-FOLLOW語法,然後將其實現為程式碼。2、使用某種語法描述語言,分析該語言的模式,並將該模式指導語法分析,即語法制導分析。一個通用的模式分析器在上半年已經完工,可以分析諸如重複、忽略、選擇等邏輯,用在語法分析其中已經足夠。但是介面尚有待改進。由於當時寫模式分析時預設模式串和目標串的iterator相同,然而世紀過程中讓呼叫者提供和目標串iterator型別一樣的模式串iterator是困難的,因為所能提供的模式串iterator多半是const char*,即呼叫時就已知的。因此更改其介面將是一個浩大的工程。而且效率也存在問題:分析一個短句子還可以,若是分析一個長達5000行的c++檔案可要耗費很多很多時間了。起碼,如果編譯效率要達到VC2003的水平,估計一個7000+行的程式應該在不超過2s時間內編譯完成,這是一個很高的要求。不過模式串分析只不過是“制導”分析,也就是說如果使用模式分析的話,也不會分析所有的細節,只不過給出一個分析框架或者步驟,具體的分析還是要靠硬編碼。至少模式分析很難在分析過程中給出語法錯誤的診斷資訊,因為模式分析的程式碼是不考慮C++語言具體情況的。