經過編譯所得的目標程式是 編譯原理筆記 01 緒論

2021-10-18 16:53:36 字數 3276 閱讀 4366

# 緒論

計算機語言間的「翻譯官」

通常來說,計算機語言分為高階語言,彙編,機器語言三種。但是能直接被計算機執行的只有機器語言,為了讓諸如c,c++之類的高階語言能執行,必須經過編譯器的轉換才行。簡單地說,編譯器就是個「翻譯官」。

而翻譯官做的是實現兩種語言之間的相互轉換,並且要保證翻譯後的語言所傳達的資訊與原語言的含義保持一致。

如翻譯以下英文:in front of my house stand two trees。

1. 首先進行詞法分析

顯然這一過程毫不費力,所以單詞均拼寫正確。

2. 進行語法分析

in front of my house 是介賓短語,stand 謂語,two jujube trees是主語。

3. 語義分析

我們依據語法知識分析了這句話大致有以下三個塊組成, [in front of my house] [stand] [two trees]。

分別對應中文是 在我的房前,站著,兩棵棗樹。

4. 繼續分析

這是乙個倒裝句,所以調整語法單位順序,得到的意思是在我的門前站著兩棵棗樹

5. 潤色

站著顯然不符合中文表達,最終翻譯成 我家門前有兩棵棗樹

事實上,編譯的過程與上述過程十分相似

源程式 ==>>[詞法分析器]>>[語法分析器]>>[語義分析與中間**產生器]>>[優化器]>>[目標**生成器] >>目標**

## 詞法分析/掃瞄(scanning)

### 主要任務

從左向右逐行掃瞄源程式的字元,識別出各個單詞,確定單詞的型別。將識別的單詞轉換成統一的機內表述---詞法單元(token)形式

token:

|         | 單詞型別  |   種別               |    種別碼 |

|    1   |  關鍵字     | if else,then...   | 一詞一碼 |   

|    2   |  識別符號     | 變數名,陣列,過程名   | 多詞一碼 |   

|    3   |    常量      | int, float.string,bool...   | 一型一碼 |   

|    4   |  運算子     | 算數(+,*,/,++),關係(>,

|    5   |  界限符     | : () = {}...          | 一詞一碼 |   

### 詞法分析例項

輸入:while(value!=100)

詞法分析器

輸出:1 while

2 ( -    >

3 value idn 識別符號

4 != -      >

5 100 100  >

6 ) -     >

7 -      >

## 語法分析

語法分析器(parse)從詞法分析器輸出的token序列中識別出各類短語,並構造語法分析樹(parse tree)

語法分析樹描述了句子的語法結構

### 賦值語句的分析樹

position = initial + rate * 20

賦值語句

識別符號  =   表示式

## 語義分析

### 任務1 收集識別符號的屬性資訊

#### 屬性種類

* 種屬:簡單變數、復合變數(陣列,記錄)、過程

* 型別:整形、實型、字元型、布林型、指標型

* 儲存位置、長度

* 值* 作用域

*  引數和返回值資訊:引數個數,型別,引數傳遞方式,返回值型別

將上述資訊,儲存在符號表中

### 任務2 語義檢查

語義錯誤 

變數/過程使用前未宣告

變數/過程 重複宣告

運算分量型別不匹配(比如,字串與整形相加)

操作符與運算元之間型別不匹配

陣列下標非整數

非陣列變數使用陣列訪問

非過程名使用過程呼叫操作符

過程呼叫的引數型別或數目不匹配

函式返回型別有錯

## 中間**生成及編譯器後端概述

### 常用的中間表示形式

1. 三位址碼(three-address code)

2. 語法結構樹/語法樹(syntax trees)

#### 三位址碼

由類似於彙編語義的指令序列組成

每個指令至多三個運算元

常用的三位址指令

賦值 x = y op z     /   x = op y

複製 x = y

條件跳轉 if x relop y goto n

非條件跳轉 goto n

引數傳遞 param x

過程呼叫 call p, n

過程返回 return x

陣列引用 x = y[i]

陣列賦值 x[i] = y

位址及指標操作 x =&y     /     x = *y     /     *x = y

#### 三位址指令的資料結構表示

##### 三位址指標的四元式(quadruples)表示

x =y op z ( op ,y ,z , x)

x = op y ( op ,y , _ , x )

x =y ( = , y , _ , x)

if x relop y goto n ( relop , x , y , n)

goto n ( goto , _ , _ , n)

param x (param, _ , _ , x)

call p,n ( call ,p , n , _ )

return x (return, _ , _ , x)

x=y[i] ( = ,y ,i ,x)

x[i] =y ( = ,y ,x ,i)

x = &y (& ,y , _ , x)

x = *y ( =* ,y , _ , x)

*x =y ( *= ,y , _ , x)

##### 三元式(triples)

##### 間接三元式(indirect triples)

### 中間**生成示例

## 編譯與解釋的區別

編譯是將使用者程式源**直接生成目標程式。

解釋語言:直接將程式作為輸入並執行,不產生目標程式。

## 參考

mooc 西安郵電大學 編譯技術

哈爾濱工業大學 編譯原理

2023年10月18日

原 tslib的交叉編譯

今天準備重新來交叉編譯qt5.3.1的原始碼,由於按網上說的,需要先編譯tslib,所以拿起來之前的編譯原始碼,打算重新用新的交叉編譯工具再次編譯一次,在查詢資料的過程中浪費了些許時間。其實直接就在使用samsung的開發板時,編譯並測試過tslib,但出於當時沒有做筆記,所以今天打算重新編譯的時候...

LCC編譯器的源程式分析 1 C編譯器的目標

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!先從簡單的目標來分析這個大規模的 c 編譯器,畢竟它的功能比較複雜,並且源程式的行數也是非常多的。因此,把簡單的目標定出來,然後再分析它,這樣才會有的放矢。接著再跟著編譯執行的主線來分析它的源程式。下面先看一下簡單的 c 例子,如下 001 inc...

程式的編譯流程

程式的基本流程如圖 1.預處理 預處理相當於根據預處理指令組裝新的c c 程式。經過預處理,會產生乙個沒有巨集定義,沒有條件編譯指令,沒有特殊符號的輸出檔案,這個檔案的含義同原本的檔案無異,只是內容上有所不同。將所有的 define 刪除,並且展開所有的巨集定義 處理所有的條件編譯指令,如 if i...