編譯器
編譯器 |
簡單講,編譯器就是將「一種語言(通常為高級語言)」翻譯為「另一種語言(通常為低級語言)」的程序。一個現代編譯器的主要工作流程:源代碼 (source code) → 預處理器 (preprocessor) → 編譯器 (compiler) → 目標代碼 (object code) → 鏈接器 (Linker) → 可執行程序 (executables)高級計算機語言便於人編寫,閱讀交流,維護。機器語言是計算機能直接解讀、運行的。編譯器將匯編或高級計算機語言源程序(Source program)作為輸入,翻譯成目標語言(Target language)機器代碼的等價程序。源代碼一般為高級語言 (High-level language), 如Pascal、C、C++、Java、漢語編程等或匯編語言,而目標則是機器語言的目標代碼(Object code),有時也稱作機器代碼(Machine code)。
目錄
簡介
編譯器可以生成用來在與編譯器本身所在的計算機和操作系統(平台)相同的環境下運行的目標代碼,這種編譯器又叫做「本地」編譯器。另外,編譯器也可以生成用來在其它平台上運行的目標代碼,這種編譯器又叫做交叉編譯器。交叉編譯器在生成新的硬件平台時非常有用。「源碼到源碼編譯器」是指用一種高級語言作為輸入,輸出也是高級語言的編譯器。例如: 自動並行化編譯器經常採用一種高級語言作為輸入,轉換其中的代碼,並用並行代碼注釋對它進行注釋(如OpenMP)或者用語言構造進行注釋(如FORTRAN的DOALL指令)。應用程序之所以複雜, 是由於它們具有處理多種問題以及相關數據集的能力。實際上, 一個複雜的應用程序就象許多不同功能的應用程序「 粘貼」 在一起。源文件中大部分複雜性來自於處理初始化和問題設置代碼。這些文件雖然通常占源文件的很大一部分, 具有很大難度, 但基本上不花費C PU 執行周期。儘管存在上述情況, 大多數Makefile文件只有一套編譯器選項來編譯項目中所有的文件。因此, 標準的優化方法只是簡單地提升優化選項的強度, 一般從O 2 到O 3。這樣一來, 就需要投人大量 精力來調試, 以確定哪些文件不能被優化, 並為這些文件建立特殊的make規則。一個更簡單但更有效的方法是通過一個性能分析器, 來運行最初的代碼, 為那些占用了85 一95 % CPU 的源文件生成一個列表。通常情況下, 這些文件大約只占所有文件的1%。如果開發人員立刻為每一個列表中的文件建立其各自的規則, 則會處於更靈活有效的位置。這樣一來改變優化只會引起一小部分文件被重新編譯。進而,由於時間不會浪費在優化不費時的函數上, 重編譯全部文件將會大大地加快。
評價
當分析問題變得好懂起來時,人們就在開發程序上花費了很大的功夫來研究這一部分的編譯器自動構造。這些程序最初被稱為編譯器的編譯器(Compiler-compiler),但更確切地應稱為分析程序生成器(Parser Generator),這是因為它們僅僅能夠自動處理編譯的一部分。這些程序中最著名的是Yacc(Yet Another Compiler-compiler),它是由Steve Johnson在1975年為Unix系統編寫的。類似的,有限狀態自動機的研究也發展了一種稱為掃描程序生成器(Scanner Generator)的工具,Lex(與Yacc同時,由Mike Lesk為Unix系統開發)是這其中的佼佼者。[1]