我是個編程初學者, 會C語言和一點點C++, 對基本的數據結構和算法有必定的瞭解, 不精通. 我對編譯原理蠻有興趣的, 因而就下定決定要寫一個編譯器. 終於在2015年暑假, 花了1個月的時間, 完成了<計算機系統要素>這本書中的編譯器項目.git
這本書介紹了一門語言jack, 這是一門簡單的面嚮對象語言, 書中只是簡單地對這門語言的規範做了點介紹而已, 沒有任何代碼指導. 僅僅有一些測試數據, 因爲我以前學了點編譯原理方面的知識, 因而我就參考這本書, 慢慢地完成了jack語言編譯器.github
我對書中的jack語言規範做了一些改進, 使這門語言更加簡潔美觀, 同時也增長了一些難度.算法
最後, 我把這門語言移植到了x86平臺下.編程
下面是一個簡單的示例:數據結構
1 class Main 2 { 3 function void main() 4 { 5 String s; 6 7 Output.printString("Hello, world!"); 8 Output.println(); 9 10 Output.printString("What's your name?"); 11 Output.println(); 12 s = Input.readLine(); 13 Output.printString("Your name is: "); 14 Output.printString(s); 15 Output.println(); 16 17 return; 18 } 19 20 }
執行 ./jackc Main.jack 就能夠把這段源程序編譯成Main.vm虛擬機代碼文件:app
1 function Main.main 1 2 push constant 13 3 call String.new 1 4 push constant 72 5 call String.appendChar 2 6 push constant 101 7 call String.appendChar 2 8 push constant 108 9 call String.appendChar 2 10 push constant 108 11 call String.appendChar 2 12 push constant 111 13 call String.appendChar 2 14 push constant 44 15 call String.appendChar 2 16 push constant 32 17 call String.appendChar 2 18 push constant 119 19 call String.appendChar 2 20 push constant 111 21 call String.appendChar 2 22 push constant 114 23 call String.appendChar 2 24 push constant 108 25 call String.appendChar 2 26 push constant 100 27 call String.appendChar 2 28 push constant 33 29 call String.appendChar 2 30 call Output.printString 1 31 pop temp 0 32 call Output.println 0 33 pop temp 0 34 push constant 17 35 call String.new 1 36 push constant 87 37 call String.appendChar 2 38 push constant 104 39 call String.appendChar 2 40 push constant 97 41 call String.appendChar 2 42 push constant 116 43 call String.appendChar 2 44 push constant 39 45 call String.appendChar 2 46 push constant 115 47 call String.appendChar 2 48 push constant 32 49 call String.appendChar 2 50 push constant 121 51 call String.appendChar 2 52 push constant 111 53 call String.appendChar 2 54 push constant 117 55 call String.appendChar 2 56 push constant 114 57 call String.appendChar 2 58 push constant 32 59 call String.appendChar 2 60 push constant 110 61 call String.appendChar 2 62 push constant 97 63 call String.appendChar 2 64 push constant 109 65 call String.appendChar 2 66 push constant 101 67 call String.appendChar 2 68 push constant 63 69 call String.appendChar 2 70 call Output.printString 1 71 pop temp 0 72 call Output.println 0 73 pop temp 0 74 call Input.readLine 0 75 pop local 0 76 push constant 14 77 call String.new 1 78 push constant 89 79 call String.appendChar 2 80 push constant 111 81 call String.appendChar 2 82 push constant 117 83 call String.appendChar 2 84 push constant 114 85 call String.appendChar 2 86 push constant 32 87 call String.appendChar 2 88 push constant 110 89 call String.appendChar 2 90 push constant 97 91 call String.appendChar 2 92 push constant 109 93 call String.appendChar 2 94 push constant 101 95 call String.appendChar 2 96 push constant 32 97 call String.appendChar 2 98 push constant 105 99 call String.appendChar 2 100 push constant 115 101 call String.appendChar 2 102 push constant 58 103 call String.appendChar 2 104 push constant 32 105 call String.appendChar 2 106 call Output.printString 1 107 pop temp 0 108 push local 0 109 call Output.printString 1 110 pop temp 0 111 call Output.println 0 112 pop temp 0 113 push constant 0 114 return
執行./jack Main.vm 便可看到運行結果:數據結構和算法
是否是以爲很是酷? 我發現不少人雖然學了編譯原理, 可是若是要實際動手去寫一個編譯器, 殊不知道如何下手. 之後我會慢慢更新個人博客, 來介紹如何寫一個編譯器!工具
另外, 學過編譯原理的人都知道, 有一些自動生成工具, 好比flex, bison等, 能夠自動幫你完成很大部分的工做. 可是個人編譯器不會藉助於這些工具, 而是全手工編寫的.測試
當時寫的完整編譯器代碼在這裏: https://github.com/Xiang1993/jack-compilerflex
其實這個編譯器其實有不少的bug的, 由於比較忙, 因此一直都沒有修復. 註釋也比較少, 並且代碼也寫得很醜, 因而我決定從新寫一遍! 新的編譯器代碼會放在這裏: https://github.com/Xiang1993/new_jack_compiler 我會慢慢更新的!
因爲快要畢業了, 之後工做了以後時間也應該不會不少, 因此個人文章可能更新地比較慢!