zoukankan      html  css  js  c++  java
  • 1, 背景介绍

        我是个编程初学者, 会C语言和一点点C++, 对基本的数据结构和算法有一定的了解, 不精通. 我对编译原理蛮有兴趣的, 于是就下定决定要写一个编译器. 终于在2015年暑假, 花了1个月的时间, 完成了<计算机系统要素>这本书中的编译器项目.

        这本书介绍了一门语言jack, 这是一门简单的面向对象语言, 书中只是简单地对这门语言的规范作了点介绍而已, 没有任何代码指导. 仅仅有一些测试数据, 由于我之前学了点编译原理方面的知识, 于是我就参考这本书, 慢慢地完成了jack语言编译器.

        我对书中的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虚拟机代码文件:

      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-compiler

        其实这个编译器其实有很多的bug的, 因为比较忙, 所以一直都没有修复. 注释也比较少, 而且代码也写得很丑, 于是我决定重新写一遍! 新的编译器代码会放在这里: https://github.com/Xiang1993/new_jack_compiler 我会慢慢更新的!

        由于快要毕业了, 以后工作了之后时间也应该不会很多, 所以我的文章可能更新地比较慢!

  • 相关阅读:
    express实现前后端通信上传图片,存储数据库(mysql)傻瓜教程(二)
    express实现前后端通信上传图片,存储数据库(mysql)傻瓜教程(一)
    [转载] 在阿里做了五年技术主管,我有话想说
    阿里云RDS MySql还原到本地Linux/Centos
    如何领域驱动设计?-实践感悟&总结分享
    jira + confluence 安装和破解
    RabbitMQ安装和配置
    [转]技术路线的选择重要但不具有决定性
    .Net core2.0日志组件Log4net、Nlog简单性能测试
    在微服务中使用领域事件
  • 原文地址:https://www.cnblogs.com/XiangfeiAi/p/4799708.html
Copyright © 2011-2022 走看看