編譯器架構Compiler Architecture(上)
編譯器是程序,通常是非常大的程序。它們幾乎都有一個基於翻譯分析綜合模型的結構。
CONTENTS
Overview • Compiler Components • Lexical Analysis (Scanning) • Syntax Analysis (Parsing) • Combining Scanning and Parsing • Semantic Analysis • Intermediate Code Generation • Machine Independent Code Improvement • Code Generation • Machine Dependent Code Improvement
Overview
編譯器執行翻譯。每一個非平凡的翻譯都需要分析和綜合:
分析和綜合都是由內部相位組成的。
Compiler Components
以下是生成彙編語言或機器語言的生產編譯器的主要功能組件(如果您只是針對C之類的高級語言或虛擬機,則可能沒有那麼多階段):
還可以標識錯誤恢復子系統和符號表管理器。
You might also identify an error recovery subsystem and a symbol table manager, too.
Lexical Analysis (Scanning)
掃描器將源程序的字符流轉換爲令牌流。這樣,它會像
刪除評論
展開宏(如C語言),
檢查縮進並創建INDENT和DEDENT標記,使用具有空格意義的語言,如Python和Haskell
刪除空白(在考慮縮進和刪除後)
An example in C:
#define ZERO 0
unsigned gcd(
unsigned int // Euclid’s algorithm
x,unsigned y)
{
while ( /* hello */ x> ZERO)
{
unsigned
temp=x;x=y %x;
y = temp ;
}
return y ;
}
標記化爲 gets tokenized into:
與掃描儀有關的問題包括:
區分大小寫(或不敏感)
空白是否重要
新行是否重要
是否可以嵌套註釋
掃描過程中可能出現的錯誤稱爲詞法錯誤,包括:
遇到不在語言字母表中的字符
單詞或行中的字符太多(是的,這種語言確實存在!)
未閉合的字符或字符串
註釋中的文件結尾
Syntax Analysis (Parsing)
解析器將令牌序列轉換爲抽象語法樹。對於上面的例子,我們得到這個樹:
樹也可以存儲爲字符串
(fundecl unsigned gcd (params (param unsigned x) (param unsigned y)) (block (while (> x 0) (block (vardecl unsigned temp y) (= x (% y x)) (= y temp))) (return y)))
從技術上講,AST中的每個節點都存儲爲一個帶有命名字段的對象,其中許多字段的值本身就是樹中的節點。注意,在編譯的這個階段,樹肯定只是一棵樹。沒有循環。
在構造解析器時,需要關注語法的複雜性(例如語法是LL還是LR),以及是否有任何可能需要破解的消歧規則。有些語言實際上需要一些語義分析來解析。
練習:說明C中的(x)-y可以有兩種不同的句法解釋。提示:你的答案可能包含“減法”、“typedef”、“cast”和“negation”。
在解析過程中可能發生的錯誤,稱爲語法錯誤,在C語言中包括如下內容。
j = 4 * (6 − x;
i = /5
42 = x * 3