這是之前學習編譯原理過程中做下的筆記。
因能力有限,在很多地方都理解不到位,特別是對於詞法分析與語法分析的過程感覺特別晦澀。
分享這個筆記也是為了自己做個總結,算是乙個小的提綱吧,都沒怎麼深入解析編譯的過程。
等以後領悟更多了再作補充吧。
希望各路人士能多加指點,謝謝。
詞法分析
作用:將輸入轉換為乙個乙個的token,而其用一串整數來表示。
協作:只有當解析器需要的時候才會請求詞法分析器,繼續掃瞄輸入流,在這個過程中將不斷生成符號表。
實現:在通常的程式語言中,相對於不確定的有限自動機(nfa),確定的有限自動機(dfa)中不會有過多的記號使得狀態數達到指數級。所以可以為每個nfa構造等價的dfa,而且最關鍵的是有限自動機的狀態數,而在沒有不確定狀態的情況下,就要求dfa將每個不確定的狀態轉換成從起始到終結狀態間的路徑,而這可能會導致增加dfa的狀態數。而在多數情況下,設計nfa要簡單些,如可通過正規表示式構建,步驟是先分解正規表示式為簡單的子表示式,並構造相應的nfa,再通過正則的運算子組合他們。
語法分析
部分概念解析
移進-歸約(shift-reduce)解析器
其中有包括待解析短語的輸入流+存放終結符以及之前歸約產生的非終結符的堆疊。
移進操作等於將符號從輸入移動到堆疊中;
歸約操作則結合已完成的序列和最後移進的終結符形成堆疊中的非終結符;
算符文法
文法中的任一產生式規則右邊不存在「空」或者兩個連續出現的非終結符;
錯誤恢復
當前棧頂的終結符和輸入的下乙個符號之間沒有任何優先關係:只允許移進下乙個輸入的字元,提前為優先表中的空白項指定恢復過程。
沒有任何產生式的右句型可以匹配當前的控制代碼:從合法規則中選擇近似的值,再報告差異錯誤;
lr分析
lr分析器一直追蹤著控制代碼的活字首,並使用自動機來識別這些活字首,其中的一些工作唄goto部分模擬了,所以不需要掃瞄堆疊中的每個輸入字元來判斷當前的狀態,因為狀態始終都是在棧頂。
型別檢查
型別檢測
包括表示式,語句,函式;
第一次是關於運算元運算子的適用性;
第二次是檢查需要確定使用的變數的定義;
型別等價
名稱等價
結構等價:建構函式
型別轉換
當強制轉換型別時,只是在那個區域性轉換,原來的型別保持不變;
符號表
內容:名稱,型別,位置,作用域,其他屬性
巢狀的詞法作用域
每個作用域單獨一張表:堆疊/列表/樹/hash
單個全域性表: 使用列表時需要額外的符號位來表示作用域;樹的話新符號都是在葉子端,刪除也要遍歷;hash存根節點;
當存放記錄項(物件)時,要訪問記錄項(物件)的不同字段(屬性),如r.a和r.b可以通過包含a,b定義的符號表來訪問;也可以將其看做r.a和r.b來訪問;
執行時環境管理
活動記錄:引數空間,簿記(bookkeeping)資訊包括返回位址,區域性變數空間,區域性臨時變數空間;
含有區域性過程的環境:
訪問變數的定義相對於當前的過程是區域性的,所以要檢視巢狀過程的活動記錄來決定;
這可以通過訪問鏈來解決;
首先計算出宣告和引用的兩個詞法巢狀層之間的差異d;
再沿著d的訪問鏈到達正確的活動記錄;
通過偏移量來訪問變數。
優化
而在搜尋訪問鏈的時候,由於是虛擬的頁面環境,可能會因為頁面交換而變得十分緩慢,為了可以不搜尋,可以使用display。
display是活動記錄的全域性指標陣列,d[i]指向巢狀深度為i的**塊中最近的活動;
所以要訪問非區域性變數x,只要最靠近x巢狀宣告的深度為i,則d[i]指向包含x的活動記錄,再根據相對位址就可以訪問x了。
中間**生成
高階表示
抽象語法樹
有向非迴圈圖:公共子表示式由單個節點構成
p-**:用於基於堆疊的虛擬機器
低階表示
三位址**
實現:四元組表示法
**生成:對於非終結符e,分別用不同屬性儲存e的值的名稱,和對應計算的三位址語句序列;
陣列:一維:(base-low * w)+i * w;(w是每個元素的寬度);二維:base+((i1 - low1) * n2 + i2 - low2) * w;
布林型別:為解決兩階段生成**問題,引入truelist, falselist和相應creatlist(i), mergelist(list1,list2), backpatch(list,target)函式;
case:當分支數量較少時可使用線性查詢/二分查詢;多則使用轉移表,若分支值不緊密聚集,空間成本會更高;
函式呼叫
目標**生成
影響因素
輸入的匹配程度,即中間**與目標**的對映程度;
目標**的結構:絕對**,可重定位,彙編;
指令集的選擇:cisc, risc;
求值次序:使用暫存器的數目;
基本塊:程式的第乙個語句;轉移目標;緊跟在轉移語句之後的語句;
暫存器分配
無向暫存器衝突圖;
圖著色;
k可著色圖:選取邊數少於k的節點t,將t壓棧並從圖中刪除它和它的所有鄰接邊,重複直至所有節點刪除;
k不可著色圖:
必須選擇節點溢位到記憶體,需要時再載入分配;
如何選取:衝突最大的;定義和使用很少的;盡量不在迴圈體內的;
使用動態規劃生成;
**優化
編譯原理 筆記
第一講 編譯過過程概述 主要介紹了 1 什麼是編譯是編譯程式?2 編譯程式的作用 3 編譯過程 4 編譯程式的組成及各部分的作用。第二講 上下文無關文法和語言 主要介紹了 1 語法 語義等概念,2 回顧了關於程式語言定義,初等資料型別,資料結構,高階高階語言的一般特性,程式結構,語句與控制結構等內容...
編譯原理筆記
機器無關的優化 基於target 的優化 生成 由於tvm中新增自定義硬體加速器的最後一步,需要llvm編譯器支援自定義pass,所以就大概看了下編譯原理,下面mark一下。編譯可大概歸納為 前端 中間 後端,下面引用教程上的一張圖 剝去源程式中的注釋和空白符。對程式開頭的巨集定義和檔案包含進行處理...
編譯原理筆記 一
編譯原理 1.1編譯器就是個程式,讀入某種語言編寫的程式,翻譯成另一種語言的程式。並能告知源程式的錯誤。1.11 編譯的分析綜合模型 編譯由兩部分組成,分析和綜合。分析部分將源程式切分成一些基本塊並形成源程式的中間表示,綜合部分把源程式的中間表示轉換成目標程式。分析期間 源程式的操作將被確定下來並表...