⑴ 一個典型的編譯程序通常由哪些部分組成
1、詞法分析
詞法分析的任務是對由字元組成的單詞進行處理,從左至右逐個字元地對源程序進行掃描,產生一個個的單詞符號,把作為字元串的源程序改造成為單詞符號串的中間程序。執行詞法分析的程序稱為詞法分析程序或掃描器。
2、語法分析
編譯程序的語法分析器以單詞符號作為輸入,分析單詞符號串是否形成符合語法規則的語法單位,如表達式、賦值、循環等,最後看是否構成一個符合要求的程序,按該語言使用的語法規則分析檢查每條語句是否有正確的邏輯結構,程序是最終的一個語法單位。
3、中間代碼生成
中間代碼是源程序的一種內部表示,或稱中間語言。中間代碼的作用是可使編譯程序的結構在邏輯上更為簡單明確,特別是可使目標代碼的優化比較容易實現。中間代碼即為中間語言程序,中間語言的復雜性介於源程序語言和機器語言之間。
4、代碼優化
代碼優化是指對程序進行多種等價變換,使得從變換後的程序出發,能生成更有效的目標代碼。所謂等價,是指不改變程序的運行結果。所謂有效,主要指目標代碼運行時間較短,以及佔用的存儲空間較小。這種變換稱為優化。
5、目標代碼生成
目標代碼生成是編譯的最後一個階段。目標代碼生成器把語法分析後或優化後的中間代碼變換成目標代碼。
(1)編譯程序的實現演算法擴展閱讀:
編譯程序把用高級程序設計語言書寫的源程序,翻譯成等價的機器語言格式目標程序的翻譯程序。編譯程序屬於採用生成性實現途徑實現的翻譯程序。它以高級程序設計語言書寫的源程序作為輸入,而以匯編語言或機器語言表示的目標程序作為輸出。
編譯出的目標程序通常還要經歷運行階段,以便在運行程序的支持下運行,加工初始數據,算出所需的計算結果。
編譯程序的實現演算法較為復雜。這是因為它所翻譯的語句與目標語言的指令不是一一對應關系,而是一多對應關系;同時也因為它要處理遞歸調用、動態存儲分配、多種數據類型,以及語句間的緊密依賴關系。
但是,由於高級程序設計語言書寫的程序具有易讀、易移植和表達能力強等特點,編譯程序廣泛地用於翻譯規模較大、復雜性較高、且需要高效運行的高級語言書寫的源程序。
⑵ c編譯程序是什麼
c編譯程序是將c語言程序編譯成目標代碼程序的程序,即正確答案應該選擇D。
1、c語言是目前世界上最流行、使用最廣泛的面向過程的高級程序設計語言。 c語言對操作系統和系統使用程序以及需要對硬體進行操作的場合,用c語言明顯優於其它高級語言,許多大型應用軟體都是用c語言編寫的。
2、編譯就是利用編譯程序從源語言編寫的源程序產生目標程序的過程,其中的五個階段分別是詞法分析、語法分析、語義檢查和中間代碼生成、代碼優化、目標代碼生成。主要是進行詞法分析和語法分析,又稱為源程序分析,分析過程中發現有語法錯誤,給出提示信息。
(2)編譯程序的實現演算法擴展閱讀
c編譯程序的語言特點
對於c編譯程序來說,其語言的特點如下:
1、c語言是一種結構化語言。它層次清晰,便於按模塊化方式組織程序,易於調試和維護,而且表現能力和處理能力極強。
2、c語言具有豐富的運算符和數據類型,便於實現各類復雜的數據結構。它還可以直接訪問內存的物理地址,進行位(bit)一級的操作。
3、由於c語言實現了對硬體的編程操作,因此集高級語言和低級語言的功能於一體。它既可用於系統軟體的開發,也適合於應用軟體的開發。
4、此外,c語言還具有效率高、可移植性強等特點。因此它廣泛地移植到了各類各型計算機上,從而形成了多種版本。
⑶ 如何更好的掌握編譯器的設計與實現
1. 閱讀相關書籍:編譯原理、編譯器設計、編譯器實現等;
2. 自學相關編程語言:C、C++、Java等;
3. 實踐:可以使用開源的編譯器框架,例如ANTLR,搭建自己的編譯器;
4. 了解編譯器的各個組成部分,並學習它們的工作原理;
5. 閱讀技術文章,了解編譯器的設計和實現的最新進展;
6. 加入開源項目,編寫和維護編譯器;
7. 在論壇上交流,和更多的編譯器開發者分享心得體會;
8. 參加學術會議,接觸到最新的研究成果;
9. 嘗試著自己設計一個編譯器,用實踐來加深理解。
⑷ 急急急,編譯原理
using namespace std;
struct BiNode
{
char data;
BiNode *lchild, *rchild;
};
typedef BiNode *BiTree;
int CreateBiTree(BiTree &T, const char *s1, const char *s2, int len)
{
if (len<=0)
{
T = NULL;
return 1;
}
else
{
T = new BiNode;
T->data = *s1;
int i;
for ( i=0; i<len; i++) if (s2[i]==*s1) break;
CreateBiTree(T->lchild, s1+1, s2, i);
CreateBiTree(T->rchild, s1+i+1, s2+i+1, len-(i+1));
}
return 1;
}
int DestroyBiTree(BiTree &T)
{
if (T==NULL) return 1;
DestroyBiTree(T->lchild);
DestroyBiTree(T->rchild);
delete T;
T = NULL;
return 1;
}
int ATraverse(BiTree &T)
{
if (T==NULL) return 1;
ATraverse(T->lchild);
ATraverse(T->rchild);
cout<<T->data;
return 1;
}
main()
{
char a[2000],b[2000];
while(cin>>a>>b)
{
BiTree T;
int count=0;
int n;
for(n=0;a[n]!='\0';n++);
CreateBiTree(T,a,b,n);
ATraverse(T);
cout<<" ";
cout<<endl;
DestroyBiTree(T);
⑸ 編譯程序有編譯和翻譯兩種方式分別對其說明並比較 急 在線等
編譯程序 編譯程序
compiler
把用高級程序設計語言書寫的源程序,翻譯成等價的計算機匯編語言或機器語言的目標程序的翻譯程序。編譯程序屬於採用生成性實現途徑實現的翻譯程序。它以高級程序設計語言書寫的源程序作為輸入,而以匯編語言或機器語言表示的目標程序作為輸出。編譯出的目標程序通常還要經歷運行階段,以便在運行程序的支持下運行,加工初始數據,算出所需的計算結果。編譯程序的實現演算法較為復雜。這是因為它所翻譯的語句與目標語言的指令不是一一對應關系,而是一多對應關系;同時也因為它要處理遞歸調用、動態存儲分配、多種數據類型,以及語句間的緊密依賴關系。但是,由於高級程序設計語言書寫的程序具有易讀、易移植和表達能力強等特點,編譯程序廣泛地用於翻譯規模較大、復雜性較高、且需要高效運行的高級語言書寫的源程序。
功能 編譯程序的基本功能是把源程序翻譯成目標程序。但是,作為一個具有實際應用價值的編譯系統,除了基本功能之外,還應具備語法檢查、調試措施、修改手段、覆蓋處理、目標程序優化、不同語言合用以及人-機聯系等重要功能。①語法檢查:檢查源程序是否合乎語法。如果不符合語法,編譯程序要指出語法錯誤的部位、性質和有關信息。編譯程序應使用戶一次上機,能夠盡可能多地查出錯誤。②調試措施:檢查源程序是否合乎設計者的意圖。為此,要求編譯程序在編譯出的目標程序中安置一些輸出指令,以便在目標程序運行時能輸出程序動態執行情況的信息,如變數值的更改、程序執行時所經歷的線路等。這些信息有助於用戶核實和驗證源程序是否表達了演算法要求。③修改手段:為用戶提供簡便的修改源程序的手段。編譯程序通常要提供批量修改手段(用於修改數量較大或臨時不易修改的錯誤)和現場修改手段(用於運行時修改數量較少、臨時易改的錯誤)。④覆蓋處理:主要是為處理程序長、數據量大的大型問題程序而設置的。基本思想是讓一些程序段和數據公用某些存儲區,其中只存放當前要用的程序或數據;其餘暫時不用的程序和數據,先存放在磁碟等輔助存儲器中,待需要時動態地調入。⑤目標程序優化:提高目標程序的質量,即佔用的存儲空間少,程序的運行時間短。依據優化目標的不同,編譯程序可選擇實現表達式優化、循環優化或程序全局優化。目標程序優化有的在源程序級上進行,有的在目標程序級上進行。⑥不同語言合用:其功能有助於用戶利用多種程序設計語言編寫應用程序或套用已有的不同語言書寫的程序模塊。最為常見的是高級語言和匯編語言的合用。這不但可以彌補高級語言難於表達某些非數值加工操作或直接控制、訪問外圍設備和硬體寄存器之不足,而且還有利於用匯編語言編寫核心部分程序,以提高運行效率。⑦人-機聯系:確定編譯程序實現方案時達到精心設計的功能。目的是便於用戶在編譯和運行階段及時了解內部工作情況,有效地監督、控制系統的運行。
早期編譯程序的實現方案,是把上述各項功能完全收納在編譯程序之中。然而,習慣做法是在操作系統的支持下,配置調試程序、編輯程序和連接裝配程序,用以協助實現程序的調試、修改、覆蓋處理,以及不同語言合用功能。但在設計編譯程序時,仍須精心考慮如何與這些子系統銜接等問題。
工作過程 編譯程序必須分析源程序,然後綜合成目標程序。首先,檢查源程序的正確性,並把它分解成若干基本成分;其次,再根據這些基本成分建立相應等價的目標程序部分。為了完成這些工作,編譯程序要在分析階段建立一些表格,改造源程序為中間語言形式,以便在分析和綜合時易於引用和加工(圖1)。
數據結構 分析和綜合時所用的主要數據結構,包括符號表、常數表和中間語言程序。符號表由源程序中所用的標識符連同它們的屬性組成,其中屬性包括種類(如變數、數組、結構、函數、過程等)、類型(如整型、實型、字元串、復型、標號等),以及目標程序所需的其他信息。常數表由源程序中用的常數組成,其中包括常數的機內表示,以及分配給它們的目標程序地址。中間語言程序是將源程序翻譯為目標程序前引入的一種中間形式的程序,其表示形式的選擇取決於編譯程序以後如何使用和加工它。常用的中間語言形式有波蘭表示、三元組、四元組以及間接三元組等。
分析部分 源程序的分析是經過詞法分析、語法分析和語義分析三個步驟實現的。詞法分析由詞法分析程序(又稱為掃描程序)完成,其任務是識別單詞(即標識符、常數、保留字,以及各種運算符、標點符號等)、造符號表和常數表,以及將源程序換碼為編譯程序易於分析和加工的內部形式。語法分析程序是編譯程序的核心部分,其主要任務是根據語言的語法規則,檢查源程序是否合乎語法。如不合乎語法,則輸出語法出錯信息;如合乎語法,則分解源程序的語法結構,構造中間語言形式的內部程序。語法分析的目的是掌握單詞是怎樣組成語句的,以及語句又是如何組成程序的。語義分析程序是進一步檢查合法程序結構的語義正確性,其目的是保證標識符和常數的正確使用,把必要的信息收集和保存到符號表或中間語言程序中,並進行相應的語義處理。
綜合部分 綜合階段必須根據符號表和中間語言程序產生出目標程序,其主要工作包括代碼優化、存儲分配和代碼生成。代碼優化是通過重排和改變程序中的某些操作,以產生更加有效的目標程序。存儲分配的任務是為程序和數據分配運行時的存儲單元。代碼生成的主要任務是產生與中間語言程序符等價的目標程序,順序加工中間語言程序,並利用符號表和常數表中的信息生成一系列的匯編語言或機器語言指令。
結構 編譯過程分為分析和綜合兩個部分,並進一步劃分為詞法分析、語法分析、 語義分析、 代碼優化、存儲分配和代碼生成等六個相繼的邏輯步驟。這六個步驟只表示編譯程序各部分之間的邏輯聯系,而不是時間關系。編譯過程既可以按照這六個邏輯步驟順序地執行,也可以按照平行互鎖方式去執行。在確定編譯程序的具體結構時,常常分若干遍實現。對於源程序或中間語言程序,從頭到尾掃視一次並實現所規定的工作稱作一遍。每一遍可以完成一個或相連幾個邏輯步驟的工作。例如,可以把詞法分析作為第一遍;語法分析和語義分析作為第二遍;代碼優化和存儲分配作為第三遍;代碼生成作為第四遍。反之,為了適應較小的存儲空間或提高目標程序質量,也可以把一個邏輯步驟的工作分為幾遍去執行。例如,代碼優化可劃分為代碼優化准備工作和實際代碼優化兩遍進行。
一個編譯程序是否分遍,以及如何分遍,根據具體情況而定。其判別標准可以是存儲容量的大小、源語言的繁簡、解題范圍的寬窄,以及設計、編制人員的多少等。分遍的好處是各遍功能獨立單純、相互聯系簡單、邏輯結構清晰、優化准備工作充分。缺點是各遍之中不可避免地要有些重復的部分,而且遍和遍之間要有交接工作,因之增加了編譯程序的長度和編譯時間。
一遍編譯程序是一種極端情況,整個編譯程序同時駐留在內存,彼此之間採用調用轉接方式連接在一起(圖2)。當語法分析程序需要新符號時,它就調用詞法分析程序;當它識別出某一語法結構時,它就調用語義分析程序。語義分析程序對識別出的結構進行語義檢查,並調用「存儲分配」和「代碼生成」程序生成相應的目標語言指令。
隨著程序設計語言在形式化、結構化、直觀化和智能化等方面的發展,作為實現相應語言功能的編譯程序,也正向自動程序設計的目標發展,以便提供理想的程序設計工具。
參考書目
陳火旺、錢家驊、孫永強編:《編譯原理》,國防工業出版社,北京,1980。
A.V.Aho, Principles of Compiler Design,Addison Wes-ley, Reading, Massachusetts, 1977.
--------------------------------------------------------------------------------
編譯程序 (compiler)
將用高級程序設計語言書寫的源程序,翻譯成等價的用計算機匯編語言、機器語言或某種中間語言表示的目標程序的翻譯程序。用戶利用編譯程序實現數據處理任務時,先要經歷編譯階段,再經歷運行階段。編譯階段以源程序作為輸入,以目標程序作為輸出,其主要任務是將源程序翻譯成目標程序。運行階段的任務是運行所編譯出的目標程序,實現源程序中指定的數據處理任務,其工作通常包括:輸入初始數據,對數據或文件進行數據加工,輸出必要信息和加工結果等。編譯程序的實現演算法較為復雜。這是因為它所翻譯的語句與目標語言的指令不是一一對應關系,而是一多對應關系;同時因為它要在編譯階段處理遞歸調用、動態存儲分配、多種數據類型 實現 、 代碼生成與代碼優化等繁雜技術問題;還要在運行階段提供良好、有效的運行環境。由於高級程序設計語言書寫的程序具有易讀、易移植和表達能力強等特點,所以編譯程序廣泛地用於翻譯規模較大、復雜性較高、且需要高效運行的高級語言書寫的源程序。
功能 編譯程序的基本功能是把源程序翻譯成目標程序。此外,還要具備語法檢查、調試措施、修改手段、覆蓋處理、目標程序優化、不同語言合用以及人機聯系等具有實際應用價值的重要功能。①語法檢查。檢查源程序是否合乎語法 。②調試措施。檢查源程序是否合乎用戶的設計意圖。③修改手段。為用戶提供簡便的修改源程序的手段。④覆蓋處理。主要為處理程序較長、數據量較大的大型問題程序而設置。基本思想是讓一些程序段和數據公用某些存儲區,其中只存放當前要用的程序段或數據,其餘暫時不用的程序段和數據均存放在磁碟等輔助存儲器中,待需要時動態地調入存儲區中運行。⑤目標程序優化。提高目標程序的質量,即使編譯出的目標程序運行時間短、佔用存儲少。⑥不同語言合用 。便於用戶利用多種程序設計語言編寫應用程序或套用已有的不同語言書寫的程序模塊。最為常見的是高級語言和匯編語言的合用。⑦人機聯系。便於用戶在編譯和運行階段及時了解系統內部工作情況,有效地監督、控制系統的運行。
早期編譯程序的實現方案,是把上述各項功能完全收納在編譯程序之中 。後來的習慣方法是在操作系統的支持下,配置編輯程序、調試程序、連接裝配程序等實用程序或工具軟體,目的是創造一個良好的開發環境和運行環境,便於應用軟體的編程、修改、調試、集成以及報表生成、界面設計等工作。但編譯程序設計者設計編譯方案時,仍需精心考慮上述各項功能,較好地解決目標程序與這些實用程序或軟體工具之間的配合與銜接等問題。
工作過程 編譯程序必須分析源程序,然後綜合成目標程序。為達到這個目的,編譯程序要在分析階段建立一些表格,改造源程序為中間語言形式,以便在分析和綜合時易於引用和加工。
數據結構 分析和綜合時所用的主要數據結構,包括符號表、常數表和中間語言程序。符號表由源程序中所用的標識符連同它們的屬性組成,其中屬性包括種類(如變數、數組、結構、函數、過程等)、類型(如整型、實型、字元串、復型、標號等),以及目標程序所需的其他信息。常數表由源程序中用的常數組成,其中包括常數的機內表示以及分配給它們的目標程序地址。中間語言程序是將源程序翻譯成目標程序前引入的一種中間形式的程序,其表示形式的選擇取決於編譯程序以後如何使用它和如何加工它。常用的中間語言形式有波蘭表示、三元組、四元組以及間接三元組等。
分析部分 源程序的分析是經過詞法分析、語法分析和語義分析三個步驟實現的。詞法分析由詞法分析程序(又稱為掃描程序 )完成,其任務是識別單詞(即標識符 、常數、保留字,以及各種運算符、標點符號等)、造符號表和常數表,以及將源程序換碼為編譯程序易於分析和加工的內部形式。語法分析程序是編譯程序的核心部分,其主要任務是根據語言的語法規則,檢查源程序是否合乎語法,並分解源程序。如果不合乎語法,則輸出語法出錯信息;如果合乎語法,則分解源程 序的語法結構, 構造中間語 言形式的內部程序。語法分析的目的是掌握單詞是怎樣組成語句的,以及語句又是如何組成程序的。語義分析程序進一步檢查合法程序結構的語義正確性,其目的是保證標識符和常數的正確使用,把必要的信息收集和保存到符號表或中間語言程序中,並進行相應的語義處理。
綜合部分 綜合階段根據符號表和中間語言程序產生出目標程序,其主要工作包括代碼優化、存儲分配和代碼生成。代碼優化是通過重排和改變程序中的某些操作,以產生更加有效的目標程序。存儲分配是為程序和數據分配運行時的存儲單元。 代碼生成是產 生與中間語 言程序等價的目標程序,亦即,順序加工中間語言程序,利用符號表和常數表中的信息生成一系列的匯編語言或機器語言指令。
動態 20世紀80年代以後,程序設計語言在形式化、結構化、直觀化和智能化等方面有了長足的進步和發展,主要表現在兩個方面:①隨著程序設計理論和方法的發展,相繼推出了一系列新型程序設計語言,如結構化程序設計語言、並發程序設計語言、分布式程序設計語言、函數式程序設計語言、智能化程序設計語言、面向對象程序設計語言等;②基於語法、語義和語用方面的研究成果,從不同的角度和層次上深刻地揭示了程序設計語言的內在規律和外在表現形式。與此相應地,作為實現程序設計語言重要手段之一的編譯程序,在體系結構、設計思想、實現技術和處理內容等方面均有不同程度的發展、變化和擴充。另外,編譯程序已作為實現編程的重要軟體工具,被納入到軟體支援環境的基本層軟體工具之中。因此,規劃編譯程序實現方案時,應從所處的具體軟體支援環境出發,既要遵循整個環境的全局性要求和規定,又要精心考慮與其他諸層軟體 工具之間的相互支援、配合和銜接關系。
⑹ 編譯器中都有哪些演算法
詞法/語法分析、程序分析與程序變換、代碼生成、內存管理、虛擬機、函數式語言的實現與優化。。。每個話題都能出不止一本書。
用到的演算法/數據結構多如牛毛:
各種樹、圖為主,其他如棧、隊列、散列表、並查集。。。
貪心、回溯、動態規劃、遺傳演算法、矩陣變換。。
在一個問題下很難回答好。。 先簡單介紹一下和圖相關的。
1. 和什麼圖打交道
CFG(Control Flow Graph)
控制流圖是對程序中分支跳轉關系的抽象,描述程序所有可能執行路徑
節點是語句集合(basic block);
每個basic block有唯一入口和出口;
如果A到B有邊,表示A執行完後可能執行B
PDG(Program Dependence Graph)
PDG在編譯器中用得不多,常見於軟體工程/安全相關的應用(程序切片、安全信息流等)
SSA(Single Static Assignment)
SSA簡化了很多數據流分析問題。
其他圖
DJ Graph, Loop Nesting Forest, Program Structure Tree等等。
可參考:IR for Program Analysis。下面主要介紹CFG
2. CFG初步處理
CFG構造
dominator樹生成
在CFG中,如果A是B的dominator,則從程序入口執行到B的任意路徑一定經過A
控制依賴分析
根據dominator和post-dominator分析依賴關系。數據依賴、控制依賴信息在自動並行化中尤其重要(如果循環的每次迭代都沒有依賴,那麼可以並行處理)
控制流圖化簡
在復雜度相同的情況下,CFG的規模影響演算法的效果。如果一個CFG僅通過如下變換能化簡為一個節點,則它是可化簡的:
如果節點n有唯一的前驅,那麼將其和其前驅合並為一個節點
如果節點存在到自身的邊,那麼將該邊刪除
構造SSA
SSA可以由CFG構造。
3. CFG與數據流分析
下面才進入主題。。
一般的文獻介紹DFA(Data flow analysis),都會用幾個基礎的分析為例:Constant Propagation,Range propagation,Avaliable expressions,Reaching Definition。而Reaching Definition的一個應用,就是大家喜聞樂見的「跳轉到定義處」(真要做到「智能」跳轉並不簡單)
這部分涉及東西較多,一些演算法也和」圖「並不直接相關,不再展開。
PS,很多DFA問題可以用graph reachability統一建模,強烈推薦此文:
Program analysis via graph reachability
⑺ 編譯程序的作用
編譯程序的作用是:將高級語言源程序翻譯成目標程序。
編譯程序是一種動作,是根據編譯原理技術,由高級程序設計語言編譯器翻譯成機器語言二進制代碼行為。編譯程序是動名詞,特指生成編譯器的軟體程序。編譯程序是把用高級程序設計語言或計算機匯編語言寫的源程序,翻譯成機器語言格式目標程序的翻譯程序。
屬於採用生成性實現途徑實現的翻譯程序。編譯程序以高級程序設計語言書寫的源程序作為輸入,而以匯編語言或機器語言表示的目標程序作為輸出;編譯出的目標程序通常還要經歷運行階段,以便在運行程序的支持下運行,加工初始數據,算出所需的計算結果。
編譯程序的演算法
編譯程序的實現演算法較為復雜。這是因為它所翻譯的語句與目標語言的指令不是一一對應關系,而是一多對應關系;同時也因為它要處理遞歸調用、動態存儲分配、多種數據類型,以及語句間的緊密依賴關系。
但是,由於高級程序設計語言書寫的程序具有易讀、易移植和表達能力強等特點,編譯程序廣泛地用於翻譯規模較大、復雜性較高、且需要高效運行的高級語言書寫的源程序。