Download presentation
Presentation is loading. Please wait.
1
第 7 章、高階語言 作者:陳鍾誠 旗標出版社
2
第 7 章、高階語言 7.1 簡介 7.2 語法理論 7.3 語意理論 7.4 執行環境 7.5 實務案例:C 語言
3
7.1 簡介 高階語言的核心是「語法理論」 利用生成規則 (例如:BNF, EBNF 等) 描述程式的語法。
7.1 簡介 高階語言的核心是「語法理論」 利用生成規則 (例如:BNF, EBNF 等) 描述程式的語法。 根據生成規則撰寫剖析程式, 轉換成語法樹。 對語法樹進行『解譯』或『編譯』的動作。
4
編譯器 v.s. 直譯器 直譯器 編譯器 利用程式解讀該語法樹, 並根據節點類型執行對應的 動作, 這樣的程式就被稱為『直譯器』。
撰寫程式將語法樹轉換為組合語言 (或目的碼), 那麼, 這樣的程式就被稱為編譯器。
5
圖 7.1高階語言的歷史年表 Fortran Cobol Lisp PL/I Smalltalk Pascal Smalltalk 80
Prolog Scheme C C++ Java Python Eiffel Ada 83 Common Lisp Tcl ML SML Caml Haskell OCaml C# Perl Ruby 1954 1956 1958 1960 1962 1964 1966 1968 1970 1972 1974 1976 1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004 2006 Algol F#
6
7.2 語法理論 高階語言所使用的語法, 大致上分為兩個層次 詞彙層次 語句層次 RE 與 CFG 都可以使用『生成規則』描述
7.2 語法理論 高階語言所使用的語法, 大致上分為兩個層次 詞彙層次 使用 Regular Expression (簡稱 RE) 語句層次 使用 Context-Free Grammar (簡稱 CFG) RE 與 CFG 都可以使用『生成規則』描述
7
生成規則 生成規則 用途 由近代語言學之父的喬姆斯基 (Chomsky) 所提出
是生成語法 (Generative Grammar) 理論的基礎 用途 用來描述「自然語言」的語法,像是中文、英文等。
8
BNF (Backus–Naur Form) 規則
由 John Backus 與 Peter Naur 所提出的規則寫法 很適合用來描述程式語言的語法 BNF 與生成規則的關係 BNF 是為了描述「程式語言」而發展出來的。 生成語法是為了描述「自然語言」所發展出來的。 兩者幾乎是同一件事,都可以描述 RE 與 CFG,因 此後來多不進行區分。
9
BNF 語法的範例 簡易的範例 英語語法的範例
10
數學運算式的語法
11
具有歧義的語法範例 E '-' N '3' '1' '2' (a). 語意:(3 - 1) - 2 = 0
(b). 語意: 3 - (1 - 2) = 4 圖 7.5 運算式 可能產生兩顆語意不同的語法樹
12
歧義性的困擾 程式語言的語法是不能有歧義性的 否則,根據圖 7.5,程式編譯後有時 3-1-2 會計算出 0, 有時卻會算出 4
否則,根據圖 7.5,程式編譯後有時 會計算出 0, 有時卻會算出 4 這樣將導致程式設計師無法確定程式的執行結果, 而陷入混亂崩潰的狀況。
13
無歧義的數學運算式語法
14
圖 7.7 數學運算式 (1+2*3) 的語法樹 E T '+' F '*' N '2' '3' '1'
15
左遞迴的問題 問題描述 解決辦法 舉例而言,規則 E = T | E [+-] T 中就有左遞迴
將左遞迴的 BNF 語法改為 EBNF 語法,以消除左遞 迴
16
EBNF 說明 Pascal 語言的發明人 Nicklaus Wirth 延伸 BNF 成為 EBNF (Extended Backus–Naur Form) 方法 加入『迴圈語法』用以代表重覆出現的意思
17
將 BNF 改為 EBNF 以便消除左遞迴問題,讓遞迴下降法可以剖析 EBNF 語法。
18
本書所使用的語法符號 (1) 中括號 大括號 代表一群字的集合 範例: [a-zA-Z] 代表 所有的英文字母
單純用來括住一個範圍,並用星號、加號、問號代表 重複次數。 範例:E = T ([+-] T)* 代表 ([+-] T) 部分可重複數次 (零次以上)。
19
本書所使用的語法符號 (2) 星號 (…)* 加號 (…)+ 問號 (…)? 代表 (…) 部分重複比對,
其中的星號 * 代表出現「零次以上」 加號 (…)+ 其中的星號 * 代表出現「一次以上」 問號 (…)? 其中的星號 ? 代表出現「零次或一次」。
20
7.3 語意理論 說明 高階語言 語意理論所探討的是語法所代表的意義, 也就是某個語法應該如何被執行, 或者如何轉換成組合語言的問題。
7.3 語意理論 說明 語意理論所探討的是語法所代表的意義, 也就是某個語法應該如何被執行, 或者如何轉換成組合語言的問題。 高階語言 語法理論 語意理論 執行平台
21
結構化程式語言 說明 範例 目前的程式語言大多屬於結構化程式語言 使用 if、for、while 作為控制邏輯
C、C++、C#、 Java、Obj C、Python、Perl
22
結構化的語意 指定:a = 5; 運算:b+3*d; 循序: s1; s2; s3; s4; …. 分支:if (…) … else (…)
迴圈:for (…) { …} , while (…) { … } 函數:f() {…}, f();
23
結構化程式的構造方式
24
7.4 執行環境 直譯式執行環境 (本章解說) 編譯式執行環境 (下一章解說) 透過直譯器直接執行高階語言程式
7.4 執行環境 直譯式執行環境 (本章解說) 透過直譯器直接執行高階語言程式 編譯式執行環境 (下一章解說) 利用編譯器將高階語言轉換為可目的檔 目的檔可在下列兩種平台上執行 虛擬機器:像是 Java 編譯後就在 JVM 虛擬機上執行。 真實機器:像是 C 語言編譯後就變成機器碼,可直接載入記 憶體後在 CPU 上執行。
25
透過直譯器執行
26
結構化程式的直譯過程
27
直譯器的演算法 (1)
28
直譯器的演算法 (2)
29
直譯器的演算法 (3)
30
7.5 實務案例:C 語言 C 語言的語法及語意 C 語言的執行環境 基本單元、指定結構、運算結構、循序結構、分支結 構、迴圈結構、函數結構
程式段、資料段、BSS段 使用框架存取參數與區域變數
31
C 語言的語法及語意 基本單元 指定結構 運算結構 循序結構 分支結構 迴圈結構 函數結構
x, 35, "hello!", x[3], f(x), f(), rec.x, rec-x, x++, x– 指定結構 a=3*x 運算結構 a * 3 + b[5] 循序結構 i=1; x=f(3); t=a; a=b; b=t; 分支結構 if(a>b) x=a; else x=b; 迴圈結構 for (i=0; i<10; i++) sum += i; 函數結構 int max(x,y) { return x>y?x:y; } c = max(a,b);
32
語法:基本單元 範例 X 35 "hello!“ x[3] f(x) f() rec.x rec->x x++ x–
33
語法:指定結構 範例 a=3*x a = b = 3*x a = (x != y)
34
語法:運算結構 範例:a * 3 + b[5] additive_exp (a*3+b) : additive_exp (a*3) + mult_exp (b[5])
35
語法:循序結構 範例 i=1; x=f(3); t=a; a=b; b=t;
36
語法:分支結構 範例: if (a>b) x=a; else x=b;
switch (c) { case ‘a’: x+=a; case ‘b’: x+=b; default: x+=c; }
37
語法:迴圈結構 範例 while (true) { …} do { … } while (! end)
for (i=0; i<10; i++) { sum += i; }
38
語法:函數結構
39
函數結構的範例 語法 範例 static int f(n) int n; {return n*n; }
function_def = decl_specs declarator decl_list compound_stat 範例 static int f(n) int n; {return n*n; } decl = static spec = int declarator = f(n) decl_list = int n; compound_stat = {return n*n; }
40
C 語言的執行環境 編譯式語言 目標:特定 CPU 的機器碼
C 語言編譯後的機器碼通常是與平台相關的, 是可以 直接被 CPU 執行的 2 進位碼, 因此速度非常的快, 這也是 C 語言的優點之一。
41
編譯與執行環境 編譯後 執行時 C 語言在執行時, 通常會編譯為目的檔或執行檔的形 式, 這個些檔案包含程式段、資料段、BSS 段等區域
在執行時還會多出堆疊 (Stack) 與堆積 (Heap) 等兩 個區段。
42
圖 7.17 C 語言的執行時的記憶體配置圖 (a) 程式開始時的記憶體分配情況 (b) 程式執行中的記憶體分配情況 程式段 .text
堆積段 (heap) 堆疊段 (stack) 資料段 .data 未初始化資料 .bss 使用中堆積區塊 已釋放區塊 (a) 程式開始時的記憶體分配情況 (b) 程式執行中的記憶體分配情況 使用中的堆疊
43
堆疊與堆積 堆疊段的用途: 堆積段的用途: 比較 儲存「區域變數」、 「參數」、 「返回點」
提供 malloc() 的空間,並在 free() 時回收。 比較 與堆積段的成長方向是相反的, 假如堆積由上往下成 長, 堆疊段的成長方向就會是由下往上。堆疊與堆積 兩段共用同一塊記憶體空間, 但是起始點與成長方向 完全相反。
44
C 語言如何存取堆疊中的區域變數 問題:必須支援遞回呼叫
因為在遞迴呼叫的過程中, 參數名稱與區域變數的名 稱雖然相同, 但是不同層次的遞迴所『看見的』變數 內容是不同的。
45
框架 一個函數的參數與區域變數所形成的堆疊區塊, 通 常稱之為框架 (Frame)
為了要存取這個框架, 我們可以設定一個框架暫存 器 (Frame Pointer, FP), 然後使用相對定址的方式 存取這些變數。 在 CPU0 中, 我們會習慣以 R11 作為框架暫存器, 因此我們也用 FP 稱呼 R11。
46
使用框架存取參數與區域變數 使用相對於框架暫存器的定址法 進入函數前設定好框架暫存器的內容
47
具有兩層函數呼叫的 C 語言程式
48
圖 7.18 函數呼叫時的堆疊與框架變化情形 … 框架指標 FP 區域變數 x 區域變數 y 參數 t (=x=1) +4 -4 -8
-4 -8 -12 FP SP y=f1(x) 返回地址 (LR) 保存的 FP 區域變數 b 參數 t (=x=1) (LR) +8 y=f1(x) 返回地址 參數 *p (=&t) b=f2(&t) 返回地址 (LR) 區域變數 r (c) 呼叫 b=f2(&t) 之後 (b) 呼叫 y=f1(x) 之後 (a) 呼叫 y=f1(x) 之前 +12
49
如何用組合語言存取堆疊中的區域變數? (main)
50
如何用組合語言存取堆疊中的區域變數? (f1)
51
如何用組合語言存取堆疊中的區域變數? (f2)
52
C 語言進入函數時的基本動作 1. 先保存連結暫存器 LR 的值, 以避免該函數再度呼叫子函數時, LR 的值會被覆蓋。
2. 接著再保存舊的框架暫存器 FP, 以便函數返回前可以恢復 FP。 3. 接著, 將框架暫存器更新為堆疊的頂端 (MOV FP, SP)。 4. 最後, 再分配好區域變數的空間之後, 前置段的工作就完成了。
53
C 語言進入函數時的基本動作 1. 先保存連結暫存器 LR 的值, 以避免該函數再度呼叫子函數時, LR 的值會被覆蓋。
2. 接著再保存舊的框架暫存器 FP, 以便函數返回前可以恢復 FP。 3. 接著, 將框架暫存器更新為堆疊的頂端 (MOV FP, SP)。 4. 最後, 再分配好區域變數的空間之後, 前置段的工作就完成了。
54
C 語言離開函數時的基本動作 1. 恢復堆疊指標 SP 2. 恢復框架指標 FP 3. 恢復連結暫存器 LR 4. 用 RET 返回呼叫點
55
結語 C 語言的語法及語意 C 語言的執行平台 基本單元、指定結構、運算結構、循序結構、分支結 構、迴圈結構、函數結構
直接編譯成目標 CPU 上的機器碼 目的檔:包含程式段、資料段、BSS段 執行時:增加堆疊段與堆積段
56
習題 7.1 請說明何謂 BNF 語法?何謂 EBNF 語法?並比較兩者的異同。
7.2 請將 BNF 語法 A = B | A '.' B 轉換為 EBNF 語法。 7.3 請寫出 C 語言當中 for 迴圈的 BNF 語法。 7.4 請說明何謂直譯器? 7.5 請說明何謂編譯器? 7.6 請比較直譯器與編譯器兩者的異同。 7.7 請說明何謂語法理論? 7.8 請說明何謂語意理論? 7.9 請說明何謂框架 ? 請舉例說明 C 語言如何利用框架暫存器存取參數與區域變數?
Similar presentations