定義
編譯程式詞組可以有兩種認識。一、編譯程式是一種動作,是根據編譯原理技術,由高級程式設計語言編譯器翻譯成機器語言二進制代碼行為。
二、編譯程式是動名詞,特指生成編譯器的軟體程式。
簡介
編譯程式的實現算法較為複雜。這是因為它所翻譯的語句與目標語言的指令不是一一對應關係,而是一多對應關係;同時也因為它要處理遞歸調用、動態存儲分配、多種數據類型,以及語句間的緊密依賴關係。但是,由於高級程式設計語言書寫的程式具有易讀、易移植和表達能力強等特點,編譯程式廣泛地用於翻譯規模較大、複雜性較高、且需要高效運行的高級語言書寫的源程式。功能
編譯程式的基本功能是把源程式翻譯成目標程式。但是,作為一個具有實際套用價值的編譯系統,除了基本功能之外,還應具備語法檢查、調試措施、修改手段、覆蓋處理、目標程式最佳化、不同語言合用以及人-機聯繫等重要功能。①語法檢查:檢查源程式是否合乎語法。如果不符合語法,編譯程式要指出語法錯誤的部位、性質和有關信息。編譯程式應使用戶一次上機,能夠儘可能多地查出錯誤。②調試措施:檢查源程式是否合乎設計者的意圖。為此,要求編譯程式在編譯出的目標程式中安置一些輸出指令,以便在目標程式運行時能輸出程式動態執行情況的信息,如變數值的更改、程式執行時所經歷的線路等。這些信息有助於用戶核實和驗證源程式是否表達了算法要求。③修改手段:為用戶提供簡便的修改源程式的手段。編譯程式通常要提供批量修改手段(用於修改數量較大或臨時不易修改的錯誤)和現場修改手段(用於運行時修改數量較少、臨時易改的錯誤)。④覆蓋處理:主要是為處理程式長、數據量大的大型問題程式而設定的。基本思想是讓一些程式段和數據公用某些存儲區,其中只存放當前要用的程式或數據;其餘暫時不用的程式和數據,先存放在磁碟等輔助存儲器中,待需要時動態地調入。⑤目標程式最佳化:提高目標程式的質量,即占用的存儲空間少,程式的運行時間短。依據最佳化目標的不同,編譯程式可選擇實現表達式最佳化、循環最佳化或程式全局最佳化。目標程式最佳化有的在源程式級上進行,有的在目標程式級上進行。⑥不同語言合用:其功能有助於用戶利用多種程式設計語言編寫應用程式或套用已有的不同語言書寫的程式模組。最為常見的是高級語言和彙編語言的合用。這不但可以彌補高級語言難於表達某些非數值加工操作或直接控制、訪問外圍設備和硬體暫存器之不足,而且還有利於用彙編語言編寫核心部分程式,以提高運行效率。⑦人-機聯繫:確定編譯程式實現方案時達到精心設計的功能。目的是便於用戶在編譯和運行階段及時了解內部工作情況,有效地監督、控制系統的運行。早期編譯程式的實現方案,是把上述各項功能完全收納在編譯程式之中。然而,習慣做法是在作業系統的支持下,配置調試程式、編輯程式和連線裝配程式,用以協助實現程式的調試、修改、覆蓋處理,以及不同語言合用功能。但在設計編譯程式時,仍須精心考慮如何與這些子系統銜接等問題。
工作過程
編譯程式必須分析源程式,然后綜合成目標程式。首先,檢查源程式的正確性,並把它分解成若干基本成分;其次,再根據這些基本成分建立相應等價的目標程式部分。為了完成這些工作,編譯程式要在分析階段建立一些表格,改造源程式為中間語言形式,以便在分析和綜合時易於引用和加工(圖1)。數據結構分析和綜合時所用的主要數據結構,包括符號表、常數表和中間語言程式。符號表由源程式中所用的標識符連同它們的屬性組成,其中屬性包括種類(如變數、數組、結構、函式、過程等)、類型(如整型、實型、字元串、復型、標號等),以及目標程式所需的其他信息。常數表由源程式中用的常數組成,其中包括常數的機內表示,以及分配給它們的目標程式地址。中間語言程式是將源程式翻譯為目標程式前引入的一種中間形式的程式,其表示形式的選擇取決於編譯程式以後如何使用和加工它。常用的中間語言形式有波蘭表示、三元組、四元組以及間接三元組等。分析部分
源程式的分析是經過詞法分析、語法分析和語義分析三個步驟實現的。詞法分析由詞法分析程式(又稱為掃描程式)完成,其任務是識別單詞(即標識符、常數、保留字,以及各種運算符、標點符號等)、造符號表和常數表,以及將源程式換碼為編譯程式易於分析和加工的內部形式。語法分析程式是編譯程式的核心部分,其主要任務是根據語言的語法規則,檢查源程式是否合乎語法。如不合乎語法,則輸出語法出錯信息;如合乎語法,則分解源程式的語法結構,構造中間語言形式的內部程式。語法分析的目的是掌握單詞是怎樣組成語句的,以及語句又是如何組成程式的。語義分析程式是進一步檢查合法程式結構的語義正確性,其目的是保證標識符和常數的正確使用,把必要的信息收集和保存到符號表或中間語言程式中,並進行相應的語義處理。綜合部分
綜合階段必須根據符號表和中間語言程式產生出目標程式,其主要工作包括代碼最佳化、存儲分配和代碼生成。代碼最佳化是通過重排和改變程式中的某些操作,以產生更加有效的目標程式。存儲分配的任務是為程式和數據分配運行時的存儲單元。代碼生成的主要任務是產生與中間語言程式符等價的目標程式,順序加工中間語言程式,並利用符號表和常數表中的信息生成一系列的彙編語言或機器語言指令。結構
編譯過程分為分析和綜合兩個部分,並進一步劃分為詞法分析、語法分析、語義分析、代碼最佳化、存儲分配和代碼生成等六個相繼的邏輯步驟。這六個步驟只表示編譯程式各部分之間的邏輯聯繫,而不是時間關係。編譯過程既可以按照這六個邏輯步驟順序地執行,也可以按照平行互鎖方式去執行。在確定編譯程式的具體結構時,常常分若干遍實現。對於源程式或中間語言程式,從頭到尾掃視一次並實現所規定的工作稱作一遍。每一遍可以完成一個或相連幾個邏輯步驟的工作。例如,可以把詞法分析作為第一遍;語法分析和語義分析作為第二遍;代碼最佳化和存儲分配作為第三遍;代碼生成作為第四遍。反之,為了適應較小的存儲空間或提高目標程式質量,也可以把一個邏輯步驟的工作分為幾遍去執行。例如,代碼最佳化可劃分為代碼最佳化準備工作和實際代碼最佳化兩遍進行。一個編譯程式是否分遍,以及如何分遍,根據具體情況而定。其判別標準可以是存儲容量的大小、源語言的繁簡、解題範圍的寬窄,以及設計、編制人員的多少等。分遍的好處是各遍功能獨立單純、相互聯繫簡單、邏輯結構清晰、最佳化準備工作充分。缺點是各遍之中不可避免地要有些重複的部分,而且遍和遍之間要有交接工作,因之增加了編譯程式的長度和編譯時間。
一遍編譯程式是一種極端情況,整個編譯程式同時駐留在記憶體,彼此之間採用調用轉接方式連線在一起(圖2)。當語法分析程式需要新符號時,它就調用詞法分析程式;當它識別出某一語法結構時,它就調用語義分析程式。語義分析程式對識別出的結構進行語義檢查,並調用“存儲分配”和“代碼生成”程式生成相應的目標語言指令。隨著程式設計語言在形式化、結構化、直觀化和智慧型化等方面的發展,作為實現相應語言功能的編譯程式,也正向自動程式設計的目標發展,以便提供理想的程式設計工具。