如何學習編譯原理中的純理論?
01-28
以前跟著虎書學過編譯,tiger語言也實現了,後來也寫過基於llvm的編譯器。但是感覺自己沒有搞懂很多理論的東西,太偏具體的實現和體系結構了。有大牛能指導一下么。
若你已經做了這麼多工程性的東西了,我覺得你可以逆推回去理論。我舉個簡單例子:比如你實現了詞法語法分析,那麼你可以把你實現的方法與編譯理論的東西再對應上去,如詞法分析的狀態機,你是如何在代碼做的,然後再體會實現的時候與理論的表達有何聯繫與不同。而在優化的時候,每一個優化的實現,如內聯,常量傳播,公共子表達式消除是怎麼做的。這樣逆回去其實對理論的理解也會比較深。
其實,編譯器開發本身也不會說先設定好理論,然後再由理論支撐實現,所以若你有志於編譯這條路,你有很強的工程經驗已經很Nice了,因為實際編譯開發真正要需要一個編譯理論來做事的機會不多,我至今只遇到過一次,是產生式提取公共因子,其餘的情況均是工程問題,包括你說的體系結構、操作系統配合等。若有志於純理論,我覺得可以考慮去國外念博士,會有更系統的培養。計算機本來就是個很工程性的東西
編譯器三大塊:前端 中間端 後端
前段已經屬於很成熟的領域了,大名鼎鼎的EDG,如果你有機會讀讀它的代碼,你會發現實現的很老實很stupid。中間端的絕大部分體系無關優化也是十幾年幾十年前的老傢伙了。連各種優化組合順序做幾遍在什麼位置哪些優化之後做都被研究的差不多了。剩下後端針對具體的體系,本來就很具體很工程化。而且主要的優化也做的差不多了。就拿llvm來說,它的greedy寄存器分配和傳統linear scan演算法的區別無外乎是優先分配live range長的還是短的。這與其說是理論,不如說是實踐上的一次靈光閃現。當然,你要是給llvm或者gcc做個圖著色還是很不錯的,但這也更多的還是工程問題。
所以,這裡不是說理論不重要,而是現代編譯器尤其是靜態編譯器的當前發展階段決定了大部分的工作都是結合理論的工程性工作。推薦閱讀:
※std::array初始化代碼編譯出現too many initializers錯誤的原因?
※【遊戲框架系列】用C++畫光(二)——矩形
※使用 AsyncListUtil 優化 RecyclerView
※《奧日與黑暗森林》這樣的遊戲主要需要哪些技術,幾個人的小團隊能實現嗎?
※[譯] 閱讀 NodeJS 文檔,我學到了這 19 件事情