原文出處: 崤嶙的博客 編譯器最基本的功能就是把高級語言(例如C/Fortran)編寫的代碼轉(zhuǎn)化為機器指令(就是01串),從這個角度來說它本質(zhì)上是個轉(zhuǎn)換過程。經(jīng)典的編譯過程主要包括: 1、詞法分析(Lexical Analysis) 2、語法分析 語法分析的輸入是一連串的token(詞法分析的輸出),根據(jù)語言的語法規(guī)則不斷解析最后得到一棵抽象語法樹(AST, Abstract Syntax Tree),負責(zé)語法分析模塊通常也被叫做Parser。在詞法分析中,我們經(jīng)常使用正則表達式來表示語言所接受的token的規(guī)則,類似的,在語法分析中,我們使用文法(Grammar)來表示語言的語法規(guī)則,這也早期計算機語言設(shè)計中的研究熱點(同樣也是大學(xué)里學(xué)習(xí)編譯時最容易讓人頭暈的東西)。 編譯里常說的文法指的是一種上下文無關(guān)文法(Context-Free Grammar),簡單地說文法里包含終結(jié)符(terminal,就是26個字符、數(shù)字等等)、非終結(jié)符(nonterminal,實際是一種抽象)和產(chǎn)生式(production)。上下文無關(guān)文法要求每個產(chǎn)生式的左邊必須恰好是一個非終結(jié)符,而右邊是0個或多個終結(jié)符與非終結(jié)符的組合,最后整個文法還必須有一個起始符(某個終結(jié)符)。文法里還有些很重要的基本概念,例如推導(dǎo)(derivation)、歸約(reduction)、二義性(ambiguity)、最左推導(dǎo)等等。 文法中最重要的基本概念是FIRST集和FOLLOW集的構(gòu)造。根據(jù)這兩個集合就可以很容易構(gòu)造出一個預(yù)測分析表,每個行的名字是一個非終結(jié)符,每個列的名字是一個終結(jié)符,如果每個表格內(nèi)沒有兩個以上的項,那么說明是一個LL(1)文法(Left-to-right parse, Leftmost-derivation, 1-symbol lookhead),簡單地說就是向右邊看一個符號就能確定下一步動作。當原文法不是LL(1)文法時,可以嘗試通過消除左遞歸(Eliminate Left Recursion)和提取左因子(Left Factoring)對原文法進行變形得到等價的LL(1)文法。 第二種文法就是LR(k)文法(Left-to-right parse, Rightmost derivation, k-token lookhead)。這種文法的解釋過程一般通過棧輔助實現(xiàn),中間主要有兩種動作:shift(就是將當前輸入入棧)和reduce(選擇產(chǎn)生式并從棧中彈出符號執(zhí)行歸約操作)。LR(0)的構(gòu)成過程就是從起始符所在的產(chǎn)生式開始構(gòu)造item,然后對每個item針對每個可能的input構(gòu)造它的出邊(同樣還是一個item),最終所有的item形成一個有限狀態(tài)機。接下來構(gòu)造有限狀態(tài)機,對于每個狀態(tài),如果出邊是一個終結(jié)符,在對應(yīng)表格記入shift操作,如果是非終結(jié)符則記入goto操作。如果S->x.這種item集,那么對每個終結(jié)符r,都記入(S, r)位置處為shift操作。 第三種SLR文法與LR(0)非常相似,區(qū)別在于生成分析表格時,對于S->x.這種item集,僅僅對于r輸入FOLLOW(S)才在(S, r)位置處記入shift操作。 最后一種LALR(1)相對于LR(0)而言引入了活前綴,構(gòu)造思路仍與LR(0)類似,但是構(gòu)造出來的預(yù)測分析表更大。 綜合起來,各文法表述能力:LL(0)<LR(0)<SLR<LALR(1)<LR(1)<LR(k),LL(1)<LR(1) 3、語義分析(Sematic Analysis) 4、中間代碼(IR, intermediate Representation)生成 5、編譯優(yōu)化 6、目標代碼生成 |
|