编译器之母

   这年头什么都讲自动化。最近要完成一个专用语言的设计,写了EBNF后,准备递归下降一直写下去,想到要一两个星期快速交出原型,倒是出了一身汗。于是祭出宝刀lex/yacc,找了个widows下的版本flex/bison,还好当年编译原理的那点底子还在,一个上午就搞定了词法分析器,写了几个专用语言文件测试,真是解释的又快又好。语法分析器就有点麻烦了,如果EBNF都写的对,可以说就没有什么障碍,可是我不敢保证我的语法写的就一定合理,一编译,就发现错误了。原来表达式定义的不合理,马上修改了语法,迅速通过。
  接下来,就是定义了抽象语法树了。定义了几种语法节点,放在bison文件的动作中,抽象语法树就建立起来了。遍历了一下语法树,觉得有点失落。虽然以前也用lex/yacc写过一些解析工具,知道这东西自动化程度很高,可是还是第一次写一个完整的语言的编译器,原本觉得应该比较复杂,没想到这么快就到语法树了,那我等程序员还拿什么混?
  中间代码生成就是自己完全手工了,写了一个效率极低的符号表先用着,等着以后重构。由于虚拟机还没有动手,就先用解释执行,可以说,没有任何悬念,一个解释器就在这么短的时间内完成了。
  后面就是虚拟机的定义和代码生成优化部分就是见功底的部分了,不敢造次,还是要慢慢来,但是编译器的原型就这样出来了。
  谈点体会,关于flex/bison的文章一大堆,我就不罗嗦了,但是在vc中使用的时候有点小技巧:对每个flex/bison的文件都可以定义custom build的动作,在这个动作写出生成cpp代码的命令就做到完全自动化了,编译的时候,只要flex/bison的文件修改了,cpp文件就重新生成。生成抽象语法树的时候,我发现要添加一个保留字,只要修改flex/bison的文件,然后一切都不用我管了,保留字的宏定义也会自动重排出来。flex/bison的特点就是生成的代码巨多宏定义和数组表,看的人头晕,不过据说还是比较可靠的,在原型出来后为了项目组的其他人能看得懂,我准备手工实现词法和语法部分,但是这个原型还是值得参考的。
  最近又看到一个好工具ANTLR,是基于LL(k)文法的,以前一直听说,没仔细看,不看不知道,一看吓一跳,这家伙可以生成java,c++,c#,python多种代码,而且生成的代码还挺适合人阅读,不像flex/bison生成的天书代码。ANTLR还有个优点,就是语法树的定义也包含了,自动生成抽象语法树,编译前端都不用操心了。看来以后我们只用关注代码生成和虚拟机部分了。
  还有一些像javacc这样的工具,我没有用过,估计功能都差不多。这些工具已经可以叫做编译器之母了。虽然商用的通用语言的编译器未必用这些工具,可是对数以千计的小语言和专用语言,这些工具在快速开发和降低难度,软件维护方面的潜力是巨大的。
  ANTLR是旧金山大学的一个教师领导的开源项目,最开始源于一位普度大学教授的课程设计。比较遗憾的是,很少有国人开发这样的工具,虽说编译前端是个研究的死领域,开发这样的工具对高校的研究生和教师来说也不是很难,但是这些工具却是这样实用,让人这样惊喜。做这样的东西我想比每年写一些没人看的论文要有意义得多吧!

你可能感兴趣的:(虚拟机,python,Build,语言,工具,编译器)