編譯過程一般可以分為6步:掃描、語法分析、語義分析、原始碼最佳化、程式碼生成和目的碼最佳化。
整個過程
- 詞法分析:掃描器掃描程式碼之後,將程式碼生成一個個token
- 語法分析:語法分析器對token進行語法分析,最後生成一個語法樹
對於不同的程式語言,可以共用一個語法分析器,因為只是將token生成一個語法樹而已,語法樹的每個節點是一個表示式
- 語義分析:透過語義分析器進行靜態語義分析,主要做宣告和型別的匹配,型別轉換這類工作。最終為語法樹的每個表示式都標識型別,也就是做了comment
- 中間語言生成:由於在對原始碼進行最佳化的時候,直接對語法樹進行分析比較困難,所以編譯器會先將整個語法樹轉成一箇中間程式碼(是語法樹的一種順序表示)
中間程式碼使得編譯器可以被分為前端和後端。編譯器前端負責產生機器無關的中間程式碼,編譯器後端將中間程式碼轉換成目標機器程式碼。這樣對於一些可以跨平臺的編譯器而言,它們可以針對不同的平臺使用同一個前端和針對不同機器平臺的數個後端。
原始碼級最佳化器產生中間程式碼標誌著下面的過程都屬於編輯器後端。編譯器後端主要包括程式碼生成器(Code Generator)和目的碼最佳化器(Target Code Optimizer)
- 目的碼生成與最佳化:
程式碼生成器將中間程式碼轉換成目標機器程式碼,這個過程十分依賴於目標機器,因為不同的機器有著不同的字長、暫存器、整數資料型別和浮點數資料型別等。最後目的碼最佳化器對上述的目的碼進行最佳化,比如選擇合適的定址方式、使用位移來代替乘法運算、刪除多餘的指令等'
最終
經過編譯,預處理後的檔案(.i
),會變成目標檔案(.o
),每個編譯單元會生成一個.o
檔案,最終多個.o
檔案經過連結,才能得到最後的可執行檔案