原文地址:蘋果梨的博客html
首先要聊聊我爲何想要寫一篇編譯原理的入門課。熟悉個人人可能會知道,我喜歡把複雜難懂的東西拆解成簡單易理解的東西,不管是在代碼的設計上,仍是在知識的分享上。另外我也是個實用主義者,寫出來的代碼光好看沒有什麼卵用,必需要有實際的用途,它纔是有價值的代碼。因此寫這樣一個系列的博客,主要有兩個目的:前端
所謂編譯器前端,主要是指詞法分析、語法分析這一類解析的過程,負責把咱們寫的代碼翻譯成計算機能夠理解的格式。編譯器後端,主要負責把前端解析獲得的中間代碼進行優化,生成CPU能夠運行的二進制代碼。編譯器後端的知識,須要對彙編、計算機組成原理之類的知識有必定了解,才能更好的理解。因此我在這裏不太打算深刻講解編譯器後端的知識,想要全面瞭解編譯原理的同窗能夠參考別的教程進行學習。git
曾經嘗試學習過編譯原理的同窗,可能會深有感觸,抱着書啃起來很枯燥,很容易從入門到放棄。編譯原理的三大著名書籍人稱龍書、虎書、鯨書,具體書名你們本身搜一下就很容易找到。咱們比較熟悉的一本應該就是下圖這個龍書——《編譯原理》,普及最廣應該是由於翻譯得比較好吧。書裏說的大部分是理論知識,極可能看完三四章後,瞭解了不少編譯器中的概念和方法,可是想要自制個編譯器就會以爲無從下手。不過這不會影響它的地位,想深刻學習編譯原理確定仍是離不開它的,建議對編譯器感興趣的同窗先從博客入門,入門後若是以爲想要更深刻,再買一本《編譯原理》回去啃也不遲。github
首推一個lotabout大佬的《手把手教你構建 C 語言編譯器》系列博客。博客從構建虛擬機開始,而後逐步的介紹詞法分析再到語法分析,圍繞着已經構建好的虛擬機一步步構造編譯器。從構造編譯器的過程上來講,大概是下圖這樣:後端
lotabout大佬的教程總結起來有如下特色:函數
編譯器完整:包含編譯器前端和編譯器後端,對了解編譯器完整工做流程有很大幫助學習
功能豐富:支持變量,條件和循環語句等複雜功能優化
較爲深刻:對虛擬機設計的講解,以及對應虛擬機的代碼生成邏輯都講得較爲深刻。這個有好有壞,好處固然是你們能學到的東西更多,壞處就是對於不瞭解CPU和彙編的同窗來講太難理解翻譯
中期沒法運行:教程中期幾篇的結尾都會有「本章的代碼還沒法正常運行」。這是必然的,編譯器必須完成完整的流程才能運行,在虛擬機的基礎上沒有完成生成代碼的邏輯,確定會沒法運行。這就可能讓中間的學習過程有必定的斷層設計
推薦的開源庫首先也是推薦lotabout大佬博客對應的GitHub開源庫:write-a-C-interpreter。光對着代碼幹啃很累,有對應的博客固然仍是學起來更快的。
而後推薦的是Fabrice Bellard大神的otcc,這應該是最迷你的C語言編譯器了,迷你但五臟俱全,甚至於能夠作到自舉(自舉就是本身能夠編譯本身)。它是當年Fabrice Bellard參加國際混淆(混亂)C語言代碼大賽的獲獎做品,能夠編譯C語言的子集。固然咱們閱讀代碼的時候請閱讀非混淆版本的,否則你的大腦可能得跟計算機同樣才能看懂寫得是什麼……
想再深刻學習代碼就試着看TinyCC吧,是Fabrice Bellard基於otcc擴展寫出來的完整的C語言編譯器,號稱最快最小。這個級別的代碼,反正我已經看不懂了……
我這裏要寫的入門課,一開始就說了不包含編譯器後端,因此這裏不能叫它編譯器,只能叫作解釋器或者說計算器。和大部分的編譯原理課不一樣,我會先寫出來能夠運行的最小單元,而後一邊展開知識範圍一邊迭代,讓解釋器能夠支持更多的功能。大概的過程會是這樣:
是否是更像是一個軟件的常規迭代過程些?入門課會有如下特徵:
目錄會以下:
(一)用最簡單的語法分析器解析加減法
(二)遞歸解析中怎麼處理運算符優先級
(三)簡單錯誤處理邏輯以及負數的解析
(四)用詞法解析處理多位數字和空白符
(五)解析ID型詞法和函數調用語法
後面還可能會補充其餘內容,要看看你們對什麼內容/功能感興趣,還要等個人懶癌被治好。
入門課對應的代碼都會開源放在GitHub:SlimeExpressionC
想要更多的功能/教學能夠在個人博客裏留言,或者到對應的開源庫下面去提issue,也熱烈歡迎大家提MR或者fork出去本身玩。今天就先水到這裏。