編譯原理與語法
㈠ 關於編譯原理中語義語法的理解
一種語言是合法句子的集合。什麼樣的句子是合法的呢?可以從兩方面來判斷:語法和語義。語法是和文法結構有關,然而語義是和按照這個結構所組合的單詞符號的意義有關。合理的語法結構並不表明語義是合法的。例如我們常說:我上大學,這個句子是符合語法規則的,也符合語義規則。但是大學上我,雖然符合語法規則,但沒有什麼意義,所以說是不符合語義的。
㈡ 編譯原理 語法
編譯原理不同教材用的表示不太一樣,翻譯也五花八門,我不是很確定你這個活前綴是什麼意思。我按我知道的告訴你,我用「。」表示狀態的位置,你的書上可能通常是一個黑點表示,先要建立文法的狀態集合:
S1:S->。a
S2:S->a。
S3:S->。^
S4:S->^。
S5:S->。(T)
S6:S->(。T)
S7:S->(T。)
S8:S->(T)。
S9:T->。T,S
S10:T->T。,S
S11:T->T,。S
S12:T->T,S。
S13:T->。S
S14:T->S。
歸集狀態,和狀態轉換關系(這應該是要畫成圖的,這里沒法畫。。。)用I表示
I0:S1 S3 S5 S9 S13
輸入a,I0->I1
I1:S2
輸入^,I0->I2
I2:S4
輸入(,I0->I3
I3:S6 S9 S13 S1 S3 S5
歸約S,I0->I4
I4:S14
歸約T,I0->I5
I5:S10
歸約T,I3->I6
I6:S7
輸入),I6->I7
I7:S8
輸入,,I5->I8
I8:S11 S1 S3 S5
歸約S,I8->I9
I9:S12
輸入a,I8->I1
輸入^,I8->I2
輸入(,I8->I3
輸入a,I3->I1
輸入^,I3->I2
輸入(,I3->I3
然後你要建立狀態轉換表,網路不能畫表格。。。,你將就看看( $是結束符啊.還有你的文法沒有開始,即S')
先把題目中的規則編個號:
(1) S->a
(2) S->^
(3) S->(T)
(4) T->T,S
(5) T->S
action goto
狀態集 a ^ ( ) , $ S T
0 s1 s2 s3 14 10
1 acc
2 acc
3 s1
因為沒有S'不知道最終怎麼規約
㈢ 什麼是編譯原理
問題一:什麼是編譯原理 編譯:就是將程序語言進行翻譯,生成可供用戶直接執行的二進制代碼,即可執行文件。
任務是個比較模糊的概念,指的是操作系統中正在進行的工作,既可以指進程,也可以指程序春坦灶。
程序指的是可以連續執行,並能夠完成一定任務的一條條指令的 *** 。
進程是程序在一個數據 *** 上運行的過程,它是傳統操作系統進行資源分配和調度的一個獨立單位。
線程是一個指令執行序列,是操作系統調度的最小單位。一個或多個線程構成進程,構成一個進激的線程之間共享資源。進程和線程之間的最大區別就是線程不能獨立擁有資源,進程擁有自己的資源。
問題二:編譯原理中V*是什麼意思 V是一個符號 *** ,假設V指的是三個符號a, b, c的 *** ,記為 V = {a, b, c }
V* 讀作「V的閉包」,它的數學定義是V自身的任意多次自身連接(乘法)運算的積,也是一個 *** 。
也就是說,用V中的任意符號進行意多次(包括0次)連接,得到的符號串,都是V*這個 *** 中的元素。
0次連接的結果是不含任何符號的空串,記為 ε
1次連接就是只有一個符號的符號串,比如,a,b, c
2次連接是兩個符號構成的符號串,比如,aa, ab, ac, ba, bb, bc,等等
……
n次連接是一個長度為n、由a、b、c三個符號構成的符號串,比如abaacbbac……
因此,V*包含一切由a,b,c三個符號連接而成的、任意長度的符號串(以及空串ε)
問題三:編譯原理 V+什麼意思,例如下面的例子。。。 v表示終結符和非終結符 *** 。
+表示 *** 中的一個或多個元素構成的串的 *** 。
所以v+表示由一個或多個終結符或非終結符構成的串的 *** 。比如如果a∈VT,A∈VN,那麼a,A,aA,Aa,aAA,AaA等都是v+中的元素。
問題四:誰能夠解釋下編譯原理中什麼是FIRSTVT,和LASTVT,盡量淺顯易懂點謝謝 Firstvt和Lastvt是為了畫算符優先關系表的(就是表裡面填優先大於小於等於的那個)。
然後要注意他們可都是終結符的 *** 。
Firstvt
找Firstvt的三條規則:如果要找A的Firstvt,A的候選式中出現:
A->a.......,即以終結符開頭,該終結符入Firstvt
A->B.......,即以非終結符開頭,該非終結符的Firstvt入A的Firstvt
攻 A->Ba.....,即先以非終結符開頭,緊跟終結符,則終結符入Firstvt
Lastvt
找Lastvt的三條規則:如果要找A的Lastvt,A的候選式中出現:
A->.......a,即以終結符結尾,該終結符入Lastvt
A->.......B,即以非終結符結尾,該非終結符的Lastvt入A的Lastvt
A->.....aB,即先以非終結符結尾,前面是終結符,則終結符入Firstvt
問題五:編譯原理 什麼是語義分析 在編譯原理中,語法規則和詞法規則不同之處在於:規則主要識別單詞,而語法主要識別多個單片語成的句子。詞法分析信孝和詞法分析程序:詞法分析階段是編譯過程的第一個階段。這個階段的任務是從左到右一個字元一個字元地讀入源程序,即對構成源程序的字元流進行掃描然後根據構詞規則識別單詞(也稱單詞符號或符號)。詞法分析程序實現這個任務。詞法分析程序可以使用lex等工具自動生成。語法分析(Syntax *** ysis或Parsing)和語法分析程序(Parser) 語法分析是編譯過程的一個邏輯階段。語法分析的任務是在詞法分析的基礎上將單詞序列組合成各類語法短語,如「程序」,「語句」,「表達式」等等.語法分扒扮析程序判斷源程序在結構上是否正確.源程序的結構由上下文無關文法描述.語義分析(Syntax *** ysis) 語義分析是編譯過程的一個邏輯階段. 語義分析的任務是對結構上正確的源程序進行上下文有關性質的審查, 進行類型審查.語義分析將審查類型並報告錯誤:不能在表達式中使用一個數組變數,賦值語句的右端和左端的類型不匹配.
問題六:編譯原理中,(E)是什麼意思? E→(E)? 10分 就是 字元本身 意思是F產生( E ) 或者 i 比如If語句的開頭 就是 帶括弧的 必須是 if(表達式)這樣的形式 丟了任何即括弧就是其 終結符 「(」 和 「)」.
問題七:大家覺得對編譯器及編譯原理需要掌握到一個什麼程度 我跟你說,編譯原理太有用了。
我是做手機游戲的,現在做一個游戲引擎。既然是引擎,就需要提供抽象的東西給上層使用。這里,我引入了腳本系統。
這個腳本系統包括一堆我根據實際需求自行設計的指令集,包括基本的輸入輸出,四則運算,系統功能調用,函數聲明,調用等等(其實你要是用過lua或者其他游戲腳本你就知道了。)整個結構包括指令集、編譯器、虛擬機等部分。這樣,引擎提供一些基礎服務,比如繪圖,計算位置等,腳本就可以非常簡單控制游戲。甚至快速構建新游戲。你應該知道QUAKE引擎吧?
這里提供給你一個計算器的小程序,應用了EBNF理論,支持表達式,比如(2+3*6)*4+4,你自己體驗一下它的簡潔和強大。
/*
simple integer arithmetic calculator according to the EBNF
-> {}
->+|-
->{}
-> *
-> ( )| Number
Input a line of text from stdin
Outputs Error or the result.
*/
#include
#include
#include
char token;/*global token variable*/
/*function prototypes for recursive calls*/
int exp(void);
int term(void);
int factor(void);
void error(void)
{
fprintf(stderr,Error\n);
exit(1);
}
void match(char expectedToken)
{
if(token==expectedToken)token=getchar();
else error();
}
main()
{
int result;
token = getchar();/*load token with first character for lookahead*/
result = exp();
if(token=='\n')/*check for end of line */
printf(Result = %d\n,result);
else error();/*extraneous cahrs on line*/
return 0;
}
int exp(void)
{
int temp = term();
while((token=='+')||(token=='-'))
switch(token)
{
case '+':
match('+');
temp+=term......>>
問題八:編譯原理中,自動機究竟是什麼. 形式語言
形式語言 是一個字母表上的某些有限長字串的 *** 。一個形式語言可以包含無限多個字串。
語言的形式定義
字母表 ∑ 為任意有限 *** ,ε 表示空串, 記 ∑ 0 為{ε},全體長度為 n 的字串為 ∑ n , ∑ * 為 ∑ 0 ∪∑ 1 ∪…∪∑ n ∪…, 語言 L 定義為 ∑ * 的任意子集。
注記:∑ * 的空子集 Φ 與 {ε} 是兩個不同的語言。
語言間的運算
語言間的運算就是 ∑ * 冪集上的運算。
字串 *** 的交並補等運算。
連接運算:L 1 L 2 = { xy | x 屬於L 1 並且 y 屬於L 2 }。
冪運算:L n = L … L (共 n 個 L 連接在一起),L 0 = {ε}。
閉包運算:L * = L 0 ∪L 1 ∪…∪L n ∪…。
(右)商運算:L 1 /L 2 = {x | 存在 y 屬於L 2 使得 xy 屬於L 1 }。
語言的表示方法
一個形式語言可以通過多種方法來限定自身,比如:
枚舉出各個字串(只適用於有限字串 *** )。
通過 形式文法 來產生(參見 喬姆斯基譜系 )。
通過正則表達式來產生。
通過某種自動機來識別,比如 圖靈機 、 有限狀態自動機 。
自動機
automata
對信號序列進行邏輯處理的裝置。在自動控制領域內,是指離散數字系統的動態數學模型,可定義為一種邏輯結構,一種演算法或一種符號串變換。自動機這一術語也廣泛出現在許多其他相關的學科中,分別有不同的內容和研究目標。在計算機科學中自動機用作計算機和計算過程的動態數學模型,用來研究計算機的體系結構、邏輯操作、程序設計乃至計算復雜性理論。在語言學中則把自動機作為語言識別器,用來研究各種形式語言。在神經生理學中把自動機定義為神經網路的動態模型,用來研究神經生理活動和思維規律,探索人腦的機制。在生物學中有人把自動機作為生命體的生長發育模型,研究新陳代謝和遺傳變異。在數學中則用自動機定義可計算函數,研究各種演算法。現代自動機的一個重要特點是能與外界交換信息,並根據交換得來的信息改變自己的動作,即改變自己的功能,甚至改變自己的結構,以適應外界的變化。也就是說在一定程度上具有類似於生命有機體那樣的適應環境變化的能力。
自動機與一般機器的重要區別在於自動機具有固定的內在狀態,即具有記憶能力和識別判斷能力或決策能力,這正是現代信息處理系統的共同特點。因此,自動機適宜於作為信息處理系統乃至一切信息系統的數學模型。自動機可按其變數集和函數的特性分類,也可按其抽象結構和聯結方式分類。主要有:有限自動機和無限自動機、線性自動機和非線性自動機、確定型自動機和不確定型自動機、同步自動機和非同步自動機、級聯自動機和細胞自動機等。
這可能有你想要的答案
./question/7218281?fr=qrl3
問題九:編譯原理中"(E)"表示什麼 字元( 表達式 字元)
㈣ 編譯原理文法
編譯原理文法的概念為:每一種自然語言或者是編程語言都需要文法來描述,文法相當於語言學的語義分析,即分析每一句話所表示的含義,編譯器需要利用文法來完成其語法分析和語義分析。
字母表是元素的非空有窮集合,字母表中的元素稱之為符號,因此,字母表也稱之為符號集。例如C語言中的字母表由字母、數字、關鍵字等組成。
符號串,就是由符號集中的元素組成的序列。例如,給定符號集a、b、c,那麼abc、abb、ac就是由該符號集組成的符號串。一個文法中,含有一個,或多個產生式,產生式,描述了將終結符集合和非終結符集合組合成串的方法。
㈤ 【編譯原理】第二章:語言和文法
上述文法 表示,該文法由終結符集合 ,非終結符集合 ,產生式集合 ,以及開始符號 構成。
而產生式 表示,一個表達式(Expression) ,可以由一個標識符(Identifier) 、或者兩個表達式由加號 或乘號 連接、或者另一個表達式用括弧包裹( )構成。
約定 :在不引起歧義的情況下,可以只寫產生式。如以上文法可以簡寫為:
產生式
可以簡寫為:
如上例中,
可以簡寫為:
給定文法 ,如果有 ,那麼可以將符號串 重寫 為 ,記作 ,這個過程稱為 推導 。
如上例中, 可以推導出 或 或 等等。
如果 ,
可以記作 ,則稱為 經過n步推導出 ,記作 。
推導的反過程稱為 歸約 。
如果 ,則稱 是 的一個 句型(sentential form )。
由文法 的開始符號 推導出的所有句子構成的集合稱為 文法G生成的語言 ,記作 。
即:
例
文法
表示什麼呢?
代表小寫字母;
代表數字;
表示若干個字母和數字構成的字元串;
說明 是一個字母、或者是字母開頭的字元串。
那麼這個文法表示的即是,以字母開頭的、非空的字元串,即標識符的構成方式。
並、連接、冪、克林閉包、正閉包。
如上例表示為:
中必須包含一個 非終結符 。
產生式一般形式:
即上式中只有當上下文滿足 與 時,才能進行從 到 的推導。
上下文有關文法不包含空產生式( )。
產生式的一般形式:
即產生式左邊都是非終結符。
右線性文法 :
左線性文法 :
以上都成為正則文法。
即產生式的右側只能有一個終結符,且所有終結符只能在同一側。
例:(右線性文法)
以上文法滿足右線性文法。
以上文法生成一個以字母開頭的字母數字串(標識符)。
以上文法等價於 上下文無關文法 :
正則文法能描述程序設計語言中的多數單詞。
正則文法能描述程序設計語言中的多數單詞,但不能表示句子構造,所以用到最多的是CFG。
根節點 表示文法開始符號S;
內部節點 表示對產生式 的應用;該節點的標號是產生式左部,子節點從左到右表示了產生式的右部;
葉節點 (又稱邊緣)既可以是非終結符也可以是終結符。
給定一個句型,其分析樹的每一棵子樹的邊緣稱為該句型的一個 短語 。
如果子樹高度為2,那麼這棵子樹的邊緣稱為該句型的一個 直接短語 。
直接短語一定是某產生式的右部,但反之不一定。
如果一個文法可以為某個句子生成 多棵分析樹 ,則稱這個文法是 二義性的 。
二義性原因:多個if只有一個else;
消岐規則:每個else只與最近的if匹配。
㈥ 編譯原理_第二章文法和語言
文法是定義或描述語法結構的一組形式盯羨規則。
G[S]=(Vn,Vt,P,S)
四元組G(
非空有限非終結符集VN,
非空有限終結符集VT,
開始符號S,
產生式集合P)
一步推導叫 直接推導 ,一步或多步推導叫 正推導 ,零步或多步推導叫 星推導 。
最左推導 每一步展開最左邊的非終結符, 最右推導 每一步展開最右邊的非終結符,最右推導又稱為 規范推導 。
規約 是推導的逆過程,最左推導的逆過程是 最右規約 ,最右推導的逆過程是 最左規約 ,最左規約又稱為 規范規約 。
設有文法G[S]:S——>Ab | C,A——>Aa| ,C——>c
S推導出的符號串是文法G的 句型。
例如推導出的Ab是一個句型;
S推導出的只含有終結符的符號串是文法G的 句子。
例如推導出的c是一個句子;
文法的 語言 是文法所有句子的集合,記為L(G)。
若兩個文法定義的語言一樣,則稱這兩個文法是等價的凱搏拍。
語銀敏法樹是一種描述上下文無關文法句型推導的直觀工具,也稱為推導樹、語法分析樹。
給定文法G,對於G的任何句型都能構造與之關聯的語法樹。
語法樹的根結點是開始符號。
如果一個結點A的直接子孫結點從左到右依次是aBcd,那麼A->aBcd一定是該文法的一個產生式。
在語法樹生長的任何時候,所有葉子結點從左到右排列起來就是一個句型。
一個文法中,如果一個句子能有不止一棵語法樹,那麼稱此句子具有二義性;如果一個文法含有二義性的句子,則該文法具有二義性。
例:句型:n=E+T*F+i
n相對於E的短語(E1的子樹):E2+T3*F3;
i是相對於T1的短語
T*F為句型n相對於產生式T——>T*E的直接短語;
i為句型n相對於產生式F——>i的直接短語
定義:一個句型的最左直接短語成為此句型的句柄
㈦ 編譯原理中詞法分析和語法分析的任務分別是什麼
在編譯原理中,語法規則和詞法規則不同之處在於:規則主要識別單詞,而語法主要識別多個單片語成的句子。
詞法分析和詞法分析程序:
詞法分析階段是編譯過程的第一個階段。這個階段的任務是從左到右一個字元一個字元地讀入源程序,即對構成源程序的字元流進行掃描然後根據構詞規則識別單詞(也稱單詞符號或符號)。詞法分析程序實現這個任務。詞法分析程序可以使用lex等工具自動生成。
語法分析(Syntax analysis或Parsing)和語法分析程序(Parser)
語法分析是編譯過程的一個邏輯階段。語法分析的任務是在詞法分析的基礎上將單詞序列組合成各類語法短語,如「程序」,「語句」,「表達式」等等.語法分析程序判斷源程序在結構上是否正確.源程序的結構由上下文無關文法描述.
語義分析(Syntax analysis)
語義分析是編譯過程的一個邏輯階段. 語義分析的任務是對結構上正確的源程序進行上下文有關性質的審查, 進行類型審查.語義分析將審查類型並報告錯誤:不能在表達式中使用一個數組變數,賦值語句的右端和左端的類型不匹配.
㈧ 編譯原理
C語言編譯過程詳解
C語言的編譯鏈接過程是要把我們編寫的一個C程序(源代碼)轉換成可以在硬體上運行的程序(可執行代碼),需要進行編譯和鏈接。編譯就是把文本形式源代碼翻譯為機器語言形式的目標文件的過程。鏈接是把目標文件、操作系統的啟動代碼和用到的庫文件進行組織形成最終生成可執行代碼的過程。過程圖解如下:
從圖上可以看到,整個代碼的編譯過程分為編譯和鏈接兩個過程,編譯對應圖中的大括弧括起的部分,其餘則為鏈接過程。
一、編譯過程
編譯過程又可以分成兩個階段:編譯和匯編。
1、編譯
編譯是讀取源程序(字元流),對之進行詞法和語法的分析,將高級語言指令轉換為功能等效的匯編代碼,源文件的編譯過程包含兩個主要階段:
第一個階段是預處理階段,在正式的編譯階段之前進行。預處理階段將根據已放置在文件中的預處理指令來修改源文件的內容。如#include指令就是一個預處理指令,它把頭文件的內容添加到.cpp文件中。這個在編譯之前修改源文件的方式提供了很大的靈活性,以適應不同的計算機和操作系統環境的限制。一個環境需要的代碼跟另一個環境所需的代碼可能有所不同,因為可用的硬體或操作系統是不同的。在許多情況下,可以把用於不同環境的代碼放在同一個文件中,再在預處理階段修改代碼,使之適應當前的環境。
主要是以下幾方面的處理:
(1)宏定義指令,如 #define a b。
對於這種偽指令,預編譯所要做的是將程序中的所有a用b替換,但作為字元串常量的 a則不被替換。還有 #undef,則將取消對某個宏的定義,使以後該串的出現不再被替換。
(2)條件編譯指令,如#ifdef,#ifndef,#else,#elif,#endif等。
這些偽指令的引入使得程序員可以通過定義不同的宏來決定編譯程序對哪些代碼進行處理。預編譯程序將根據有關的文件,將那些不必要的代碼過濾掉
(3) 頭文件包含指令,如#include "FileName"或者#include <FileName>等。
在頭文件中一般用偽指令#define定義了大量的宏(最常見的是字元常量),同時包含有各種外部符號的聲明。採用頭文件的目的主要是為了使某些定義可以供多個不同的C源程序使用。因為在需要用到這些定義的C源程序中,只需加上一條#include語句即可,而不必再在此文件中將這些定義重復一遍。預編譯程序將把頭文件中的定義統統都加入到它所產生的輸出文件中,以供編譯程序對之進行處理。包含到C源程序中的頭文件可以是系統提供的,這些頭文件一般被放在/usr/include目錄下。在程序中#include它們要使用尖括弧(<>)。另外開發人員也可以定義自己的頭文件,這些文件一般與C源程序放在同一目錄下,此時在#include中要用雙引號("")。
(4)特殊符號,預編譯程序可以識別一些特殊的符號。
例如在源程序中出現的LINE標識將被解釋為當前行號(十進制數),FILE則被解釋為當前被編譯的C源程序的名稱。預編譯程序對於在源程序中出現的這些串將用合適的值進行替換。
預編譯程序所完成的基本上是對源程序的「替代」工作。經過此種替代,生成一個沒有宏定義、沒有條件編譯指令、沒有特殊符號的輸出文件。這個文件的含義同沒有經過預處理的源文件是相同的,但內容有所不同。下一步,此輸出文件將作為編譯程序的輸出而被翻譯成為機器指令。
第二個階段編譯、優化階段。經過預編譯得到的輸出文件中,只有常量;如數字、字元串、變數的定義,以及C語言的關鍵字,如main,if,else,for,while,{,}, +,-,*,\等等。
編譯程序所要作得工作就是通過詞法分析和語法分析,在確認所有的指令都符合語法規則之後,將其翻譯成等價的中間代碼表示或匯編代碼。
優化處理是編譯系統中一項比較艱深的技術。它涉及到的問題不僅同編譯技術本身有關,而且同機器的硬體環境也有很大的關系。優化一部分是對中間代碼的優化。這種優化不依賴於具體的計算機。另一種優化則主要針對目標代碼的生成而進行的。
對於前一種優化,主要的工作是刪除公共表達式、循環優化(代碼外提、強度削弱、變換循環控制條件、已知量的合並等)、復寫傳播,以及無用賦值的刪除,等等。
後一種類型的優化同機器的硬體結構密切相關,最主要的是考慮是如何充分利用機器的各個硬體寄存器存放的有關變數的值,以減少對於內存的訪問次數。另外,如何根據機器硬體執行指令的特點(如流水線、RISC、CISC、VLIW等)而對指令進行一些調整使目標代碼比較短,執行的效率比較高,也是一個重要的研究課題。
2、匯編
匯編實際上指把匯編語言代碼翻譯成目標機器指令的過程。對於被翻譯系統處理的每一個C語言源程序,都將最終經過這一處理而得到相應的目標文件。目標文件中所存放的也就是與源程序等效的目標的機器語言代碼。目標文件由段組成。通常一個目標文件中至少有兩個段:
代碼段:該段中所包含的主要是程序的指令。該段一般是可讀和可執行的,但一般卻不可寫。
數據段:主要存放程序中要用到的各種全局變數或靜態的數據。一般數據段都是可讀,可寫,可執行的。
UNIX環境下主要有三種類型的目標文件:
(1)可重定位文件
其中包含有適合於其它目標文件鏈接來創建一個可執行的或者共享的目標文件的代碼和數據。
(2)共享的目標文件
這種文件存放了適合於在兩種上下文里鏈接的代碼和數據。
第一種是鏈接程序可把它與其它可重定位文件及共享的目標文件一起處理來創建另一個 目標文件;
第二種是動態鏈接程序將它與另一個可執行文件及其它的共享目標文件結合到一起,創建一個進程映象。
(3)可執行文件
它包含了一個可以被操作系統創建一個進程來執行之的文件。匯編程序生成的實際上是第一種類型的目標文件。對於後兩種還需要其他的一些處理方能得到,這個就是鏈接程序的工作了。
二、鏈接過程
由匯編程序生成的目標文件並不能立即就被執行,其中可能還有許多沒有解決的問題。
例如,某個源文件中的函數可能引用了另一個源文件中定義的某個符號(如變數或者函數調用等);在程序中可能調用了某個庫文件中的函數,等等。所有的這些問題,都需要經鏈接程序的處理方能得以解決。
鏈接程序的主要工作就是將有關的目標文件彼此相連接,也即將在一個文件中引用的符號同該符號在另外一個文件中的定義連接起來,使得所有的這些目標文件成為一個能夠被操作系統裝入執行的統一整體。
根據開發人員指定的同庫函數的鏈接方式的不同,鏈接處理可分為兩種:
(1)靜態鏈接
在這種鏈接方式下,函數的代碼將從其所在地靜態鏈接庫中被拷貝到最終的可執行程序中。這樣該程序在被執行時這些代碼將被裝入到該進程的虛擬地址空間中。靜態鏈接庫實際上是一個目標文件的集合,其中的每個文件含有庫中的一個或者一組相關函數的代碼。
(2) 動態鏈接
在此種方式下,函數的代碼被放到稱作是動態鏈接庫或共享對象的某個目標文件中。鏈接程序此時所作的只是在最終的可執行程序中記錄下共享對象的名字以及其它少量的登記信息。在此可執行文件被執行時,動態鏈接庫的全部內容將被映射到運行時相應進程的虛地址空間。動態鏈接程序將根據可執行程序中記錄的信息找到相應的函數代碼。
對於可執行文件中的函數調用,可分別採用動態鏈接或靜態鏈接的方法。使用動態鏈接能夠使最終的可執行文件比較短小,並且當共享對象被多個進程使用時能節約一些內存,因為在內存中只需要保存一份此共享對象的代碼。但並不是使用動態鏈接就一定比使用靜態鏈接要優越。在某些情況下動態鏈接可能帶來一些性能上損害。
我們在linux使用的gcc編譯器便是把以上的幾個過程進行捆綁,使用戶只使用一次命令就把編譯工作完成,這的確方便了編譯工作,但對於初學者了解編譯過程就很不利了,下圖便是gcc代理的編譯過程:
從上圖可以看到:
預編譯
將.c 文件轉化成 .i文件
使用的gcc命令是:gcc –E
對應於預處理命令cpp
編譯
將.c/.h文件轉換成.s文件
使用的gcc命令是:gcc –S
對應於編譯命令 cc –S
匯編
將.s 文件轉化成 .o文件
使用的gcc 命令是:gcc –c
對應於匯編命令是 as
鏈接
將.o文件轉化成可執行程序
使用的gcc 命令是: gcc
對應於鏈接命令是 ld
總結起來編譯過程就上面的四個過程:預編譯、編譯、匯編、鏈接。了解這四個過程中所做的工作,對我們理解頭文件、庫等的工作過程是有幫助的,而且清楚的了解編譯鏈接過程還對我們在編程時定位錯誤,以及編程時盡量調動編譯器的檢測錯誤會有很大的幫助的。
是否可以解決您的問題?
㈨ 【編譯原理】第四章:語法分析
從分析樹的根節點到葉節點方向構造分析樹。
即從開始符號S推導出詞串w的過程。
例:
總是選擇每個句型的 最左非終結符 進行替換。
總是選擇每個句型的 最右非終結符 進行替換。
在自底向上的分析中,總是採用 最左規約 的方式,因此把 最左規約 稱為 規范規約 ,對應的 最右推導 稱為 規范推導 。
最左推導、最右推導具有唯一性。
自頂向下的語法分析採用最左推導方試,總是選擇每個句型的 最左非終結符 進行替換。
由一組 過程 組成,每一個過程對應一個 非終結符 。
從文法開始符號S開始,遞歸調用文法中的其他非終結符,最終掃描整個輸入串,完成分析。
如果其間有不唯一的產生式,就可能需要退回上一步重新嘗試的情況,稱為 回溯 。
預測分析 是 遞歸下降分析 技術的一個特例,通過輸入中向前看固定個數的符號選擇正確的產生式。
如果一個文法可以構造出向前看k個符號的預測分析器,稱為LL(k)文法 。
預測分析不需要回溯,具有確定性。
含有 形式產生式的文法稱為是 直接左遞歸 的。
如果一個文法中有一個非終結符A使得對某個串存在推導 ,那麼這個文法是 左遞歸 的。其中,經過兩步或以上推導產生的左遞歸,稱為 間接左遞歸 的。
左遞歸會使遞歸下降分析器陷入無限循環。
文法
即
該文法是直接左遞歸的,會陷入無限循環。
將以上文法轉換為:
即可消除左遞歸。事實上,這個過程把左遞歸轉換成了右遞歸。
消除直接左遞歸的一般形式
使用代入法。
對於一個文法,通過改寫產生式來 推遲決定 ,等獲得足夠多的輸入信息再做正確的決定。
例:文法:
可以改寫為:
從文法的開始符號S開始,每一步推導根據當前句型的最左非終結符A和當前輸入符號α,選擇正確的A-產生式。為保證分析的確定性,選出的候選式必須是唯一的。
S_文法(簡單的確定型文法)
可能在某個舉行中緊跟在A後面的終結符a的集合,記為 FOLLOW(A) 。
如果A是某個句型的最右符號,則將結束符「 $ 」添加到FOLLOW(A)中。
例:文法:
中,FOLLOW(B) = {a, c}
產生式 的可選集是指可以選用該產生式進行推導時對應的輸入符號的集合,記為 SELECT(A->β) 。
例如
SELECT(A -> aβ)={a}
SELECT(A -> aβ | bγ)={a, b}
SELECT(A -> ε)=FOLLOW(A)
q_文法
文法符號串α串首終結符的集合,記作 FIRST(A) 。
㈩ 如何通俗易懂地解釋編譯原理中語法分析的過程
語法分析(Syntax analysis或Parsing)和語法分析程序(Parser)
語法分析是編譯過程的一個邏輯階段。語法分析的任務是在詞法分析的基礎上將單詞序列組合成各類語法短語,如「程序」,「語句」,「表達式」等等.語法分析程序判斷源程序在結構上是否正確.源程序的結構由上下文無關文法描述.