開篇:
做爲軟件工程專業的一員,在本科時候,關於《編譯原理》這門課,沒有開,沒有開,沒有開。。。只能通過自己學習來深入瞭解編譯原理。並希望能夠達到實現一個簡單編譯器的地步。
- 1 語言處理器
關於語言處理器,其本身就是一個大程序,而這個大程序的主要目的在於翻譯源程序。
以Java爲例,有時候,我們可能會有疑問,當寫完一段或複雜或簡單的業務邏輯程序之後,計算機是如何去執行這段源程序的?
這時候,就需要語言處理器去將源程序翻譯爲目標機器代碼供計算機執行。在計算機誕生之初,機器代碼過於晦澀難懂,不易理解和上手使用,所以誕生了更接近人類自然語言的高級程序設計語言(早期的Fortran和C),那麼問題就來了,計算機並不能讀懂這些高級程序設計語言,或者說,計算機並不能理解這些高級程序設計語言的語法和語義。因此就需要語言處理器去翻譯和處理,並在最後執行這些源程序。
語言處理器總體上分爲兩類:編譯器和解釋器
- 編譯器:本身編譯器即爲一個程序,只將源程序翻譯成機器可以理解的目標機器代碼,同時收集與源程序相關的變量信息存放於指定位置供後續翻譯使用,而這個指定位置叫做符號表,翻譯完畢之後,編譯器會將目標機器代碼作爲輸出,供後續使用。整個翻譯的過程較爲複雜,這裏只做總體認識。
- 解釋器:解釋器相比於編譯器,有一個很大的不同之處就在於,他並不像編譯器那樣對源程序進行翻譯,而是直接將源程序配合用戶的輸入通過解釋器去一步步執行源程序,並直接產生結果輸出。
- 兩者的優劣:從上述對比其實可以發現,編譯器並不執行源程序,僅僅是一個翻譯的過程,所以從速度上來說,編譯器會快於解釋器,但是相反,由於解釋器會直接執行源程序,所以在執行過程中,對源程序的語義和語法的檢查將比編譯器更加精確。
而在實際生產環境中,源程序往往是分佈於各個獨立的文件之中,這些獨立的文件需要經過一個叫做“聚合”的階段,才能進行下一步的編譯操作。而負責聚合操作的對象,叫做所謂的預處理器。而預處理器的聚合操作僅僅是語言處理系統的第一步。
預處理器的主要作用就是對源程序進行聚合操作,得到聚合源程序後,再又彙編器生成目標彙編程序,彙編程序再又彙編器生成可重定位的機器代碼(因爲大型程序都是通過多部分各自編譯的方式進行的),最後利用鏈接器將可重定位的機器代碼與庫文件及可重定位對象文件進行鏈接,並交由加載器將最終得到的機器代碼放置內存中運行。
這裏需要強調幾個概念:
- 彙編器:由於彙編程序易於輸出和調試,因此在大型程序中會首選彙編器將源程序先翻譯成彙編語言。彙編器也是編譯器的一種。
- 鏈接器:由於大型程序會被分成多個部分進行編譯,因此生成的機器代碼必須是可重定向的,因爲後續需要將其與庫文件和可重定向的其他目標文件鏈接到一起。
- 加載器:負責將所有的可執行的目標文件放到內存中執行。
- 2 編譯器結構
- 3 程序設計語言發展