總結

恭喜你完成了自己的 C 語言編譯器,本章中我們發一發牢騷,說一說編寫編譯器值得注意的一些問題;編寫編譯器時遇到的一些難題。

##虛擬機與目標代碼

整個系列的一開始,我們就著手虛擬機的實現。不知道你是否有同感,這部分對於整個編譯器的編寫其實是十分重要的。我認為至少佔了重要程度的50%。

這裡要說明這樣一個觀點,學習編譯原理時常常著眼於詞法分析和語法分析,而忽略了同樣重要的代碼生成。對於學習或考試而言或許可以,但實際編譯項目時,最為重要的是能“跑起來”,所以我們需要給予代碼生成高度的重視。

同時我們也看到,在後期解析語句和表達式時,難點已經不再是語法分析了,而是如何為運算符生成相應的彙編代碼。

##詞法分析

我們用了很暴力的手段編寫了我們的詞法分析器,我認為這並無不可。

但你依舊可以學習相關的知識,瞭解自動生成詞法分析器的原理,它涉及到了“正則表達式”,“狀態機”等等知識。相信這部分的知識能夠很大程度上提高你的編程水平。

同時,如果今後你仍然想編寫編譯器,不妨試試這些自動生成工具。

##語法分析

長期以來,語法分析對我而言一直是迷一樣的存在,直到真正用遞歸下降的方式實現了一個。

我們用了專門的一章講解了“遞歸下降”與 BNF 文法的關係。希望能減少你對理論的厭惡。至少,實現起來並不是太難。

如果有興趣,可以學習學習這些文法,因為已經有許多自動生成的工具支持它們。這樣你就不需要重複造輪子。可以看看 yacc 等工具,更先進的版本是 bsion。同時其它語言也有許多類似的支持。

題外話,最近知道了一個叫“PEG 文法”的表示方法,無論是讀起來,還是實現起來,都比 BNF 要容易,你也可以學習看看。

##關於編代碼

這也是我自己的感慨吧。無論多好的教程,想要完全理解它,最好的方式恐怕還是要自己實現它。

只是在編寫代碼的過程中,我們會遇到許多的挫折,例如需要考慮許多細節,或是調試起來十分困難。但也只有真正靜下心來去克服它,我們才能有所成長吧。

例如在編寫表達式的解析時,大量重複的代碼特別讓人崩潰。還有就是調試編譯器,簡直痛苦地無話可說。

P.S. 如果你按這個系列自己編寫代碼,記得事先寫一些用於輸出彙編代碼的函數,很有幫助的。

還有就是寫這個系列的文章,開始的衝動過了之後,每寫一篇都特別心煩,希望文章本身沒有受我的這種情緒影響吧。

##結語

編程有趣又無趣,只有身在其中的我們才能體會吧。


书籍推荐