最近,在看了《自己动手写编译器,链接器》之后,便打算按照书中的思路,来完成一个sc语言的编译器scc。由于我对scala较为熟悉,所以自此开始着手进行lexer和parser的编写。
抛弃那些专业术语,从业余的角度来讲,要完成对源码的解析和分割,着色和打印,需要解决以下几个问题。
1. 按字节读取源码,能够提前读取下一个或者多个字节内容然后回退到未读的状态。
在java中已经有现成的工具类PushBackInputStream,能够在尝试读取多个字节内容后回退到未读状态。
2. 空格和换行的处理。
由于sc语言以括号和分号结尾,所以对于任何空格和换行,都以跳过处理。
3. 确定各种类型的Token以及处理的方式。
由于书中已经给出了sc语言的定义,关键字的详细说明和处理方式,所以只需要按部就班就可以完成对源码全文的处理。
4.文法解析以及打印时缩进和换行的控制。
根据书中给出的BNF文法定义,依次写出整个源码的文法解析规则。由于书中有对应的解释和示例代码,所以使用scala改写时并无难度。同时,为了控制缩进和换行,引入了两个全局变量(当然用scala改写时作为构造参数全局传递),分别控制缩进等级和是否换行。
可能遇到的问题和解决方案都已经说明,接下来就只需要完成代码的填补就好。但是在实际编写调试过程中也遇到了不少问题。一方面是由于语言的差异(书中以c语言编写),另一方面在某些细节地方,我觉得书中给出的编码实现跟实际的文法定义并不符合,于是做出了一些修改。当然印象最深刻的是在一个多处使用的方法中添加参数时,隐式转换带来的巨大便利。如果以c语言或者java语言来编写程序,需要在一个已经在多处使用的方法添加参数时,除非该方法的最初定义就考虑到以后可能会有的变动,否则添加任何一个参数都会带来很多无意义的工作。而scala自身所包含的隐式参数,能够非常方便的在不大幅修改原有代码的基础上,完美添加新的参数,完成对功能的修改。
附成果图:
链接:https://github.com/JYInMyHeart/scc
来源:CSDN
作者:JAVAInMyHeart
链接:https://blog.csdn.net/JAVAInMyHeart/article/details/81062288