1. 程式人生 > >一、編譯器構造一般原理

一、編譯器構造一般原理

一、編譯器概述

1.翻譯器(translator):把一種語言程式翻譯成另一種語言程式。

2.編譯器(compiler):高階語言變成低階語言。

3.直譯器(interpreter):將語句一條一條直接執行,而不生成目的碼。

4.編譯器階段:源程式->詞法分析->語法分析->語義分析->中間程式碼生成器->獨立於機器程式碼優化器->程式碼生成器->依賴於機器程式碼優化器。

5.詞法分析器(lexical analysis,scanner):

將字元序列轉化為單詞序列(token)的過程,如將position=initial+rate*60轉化,通過詞法分析器轉化為如下

<id,1>,<=>,<id,2>,<+>,<id,3>,<*>,<60>,其中符號表為:1.position,2.initial,3.rate ...

6.語法分析器(syntactic analysis,parser):

將position=initial+rate*60經過詞法分析得到的序列構造成一棵分析樹(parse tree),如下

符號表:1.position,2.initial,3.rate ...(也包含型別資訊)

7.語義分析器(semantic analysis):

輸入語法樹,輸出也是語法樹,收集識別符號種屬、型別、儲存位置長度、值、引數返回等資訊,存到符號表中,並進行語義檢查。

8.中間程式碼生成器(intermediate code generator):將上述語法樹生成中間程式碼如下(三地址指令)

t1=int-to-real(60)

t2=id3*t1

t3=id2+t2

id1=t3

9.程式碼優化器(code optimizer):中間程式碼優化器可得到如下

t1=id3*60.0

id1=id2+t1

10.程式碼生成器(code generator):生成彙編程式碼或機器碼。

11.詞法分析器與語法分析器關係:語法分析器作為主程式,呼叫詞法分析器取下一個token,詞法分析器取好返回給語法分析器,在這個過程期間它們都要訪問符號表。(語法分析器後面還可能會呼叫語義分析器)

二、詞法基本概念

1.字母表(alphabet):表示字母的集合,記號為Σ,若Σ={0,1}則字母表中只有0或1。

2.字母表乘積(product):Σ1Σ2=Σ3,則Σ3中存在兩個字母,前一個字母在Σ1集合中,後一個字母在Σ2集合中。

3.字母表的冪(power):字母表的n次冪表示長度為n的符號串構成的集合,這些符號在字母表集合內。

4.字母表閉包(closure):由字母表中字母構成的所有串(包括空串),若為正(positive)閉包則不包含空串。

5.串(string):符號的有窮序列,空串記為ε,通常用|s|記作串s的長度。

6.串的連線(concatenation):如xy連線aa就等於xyaa,即追加串。

7.串的冪:(ab)^3=ababab,任何串0次冪為ε。

8.串的閉包:(ab)*為{ε,ab,abab,ababab,abababab,......}即(ab)^0並(ab)^1並...,若為正閉包則去掉空串。

9.語言(language):字母表上的一個串集,如{ε,0,00,000}或者Ø

10.語言的並運算:LM=結合了兩種語言的語言。

11.語言的連線運算:LM=每一個句子的前一部分一定屬於L語言,後一部分一定屬於M語言。

12.語言的冪:L^0={ε},L^i為語言所有句子的i次連線。

13.語言的閉包:L*=L^0並L^1並L^2並....,若正閉包則去掉L^0。

三、文法基本概念

1.文法形式化定義:

G=(Vt,Vn,P,S)

Vt為終結符(terminal symbol)集合,終結符也稱token。

Vn為非終結符(nonterminal)集合,非終結符是表示語法成分的符號。

P為產生式(production)集合,描述了將終結符和非終結符組合成串的方,形式為a b,讀作a定義為b,這裡要求a必須包含至少一個非終結符。

S為開始符號(start symbol),表示該文法中最大的語法成分。

文法解決了無窮語言的有窮表示問題。

2.文法的例子:

G=( {id,+,*,(,)} , {E} , P , E )

P={ E E+E , E E*E , E (E) , E id }

3.產生式簡寫:a b1,a → b2,a → b3 可簡寫為  a → b1 | b2 | b3 。

4.推導(derivations):A B,B → (id) 推導為 A → (id) ,將最大語法成分推導為終結符組成的串。

5.歸約(reductions):由上例,A → (id) 可歸約為 A B ,推導逆操作,將終結符組成的串歸約為最大語法成分

6.句型(sentential form):一個句型可包含終結符,又可包含非終結符,也可能是空串。

7.句子(sentence):不包含非終結符的句型。

8.文法分類:

0型文法(無限制文法):任意a b,a中至少包含1個非終結符,能力相當於圖靈機。

1型文法(上下文有關文法):0型文法基礎上,任意a b,|a| <= |b| (b不等於ε),如 aAb axb 上下文有關

2型文法(上下文無關文法,context-free grammar):每個產生式左部必須是非終結符,A b 。

3型文法(正則文法,regular grammar):A wB或A w(右線性),A Bw或A w(左線性)。

9.上下文無關文法的分析樹:

根為文法開始符號,內部結點為某產生式的左部,一個內部結點和兒子構成了某產生式,分析樹是推導的圖形化表示。

分析樹中根結點對應子樹的邊緣對應句型短語(phrase)本例 id*id+id 。

10.最左推導和最後推導(left/right-most derivation):

例如給出如下產生式 E E+E | E*E | (E) | -E | id

最左推導:推導過程中每次對最左邊的非終結符展開。

E -E → -(E) → -(E+E) → -(id+E) → -(id+id)

最右推導(規範推導):每次對最右邊的非終結符展開。

E -E → -(E) → -(E+E) → -(E+id) → -(id+id)

注:最左推導和最右推導的分析樹是一樣的。

11.相同句子分析樹的二義性(同為最左推導):.

對於產生式 E E+E | E*E | (E) | -E | id,要得到句子id*id+id,在最左推導的情況下,可以有這兩種分析樹。

消除由運算優先順序產生的二義性,可以這樣定義文法

id*id*(id+id) + id*id + id    我們把加式連一塊看作一個expr,把乘式連一塊看作一個term。

id * id * (id+id)    連乘式中每一項看作一個因子factor。

文法就定義為:

expr expr+term | term

term term*factor | factor

factor id | (expr)

例題1:

描述下述語言 L={(a^n) (d^m) (b^n),n,m>=1}

解:

A aAb | aBb    前面的aAb表示可一直延伸ab,即為 ...aaAbb... ,後面的aBb表示B可被d換

B dB | d    即表示dd...

例題2:

證明下列文法是一個二義文法

A B+B | B

B B*B | A | a

解:

對於相同句子a+a*a,同是最左推導時,存在以下兩個不同的分析樹,因此為二義文法。

A B+Ba+Ba+B*Ba+a*Ba+a*a

ABB*B A*B B+B*B a+B*B a+a*B a+a*a