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