【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
和其他的编译器专栏相比较,这里的编译器只是侧重于对单一的文法进行处理。主要还是以四则运算为主。要说语法层面的话,相当于c语言里面的expression语法。虽然,这个语法的内容并不多,但是我们可以把这部分作为基础,一步一步去理解、分析、实现背后的逻辑。通过做深做透单一知识点,可以更好地去了解编译的全流程。这是这个系列和其他编译器文章最大的不同。
读书的时候,很多时候由于时间的限制,往往只要求学生掌握词法分析,或者是到语法分析,对于后面的内容完全不做要求。其实,这是不对的。对于学习来说,哪怕是再简单的内容,也要手写几遍,通过过程中出现的错误来加深自己的理解。最好有一个简单的语法,帮助同学们掌握全流程的知识点。当然,也不是说书本理论不重要,而是说理论要联系实际才重要。光讲理论,只会流于形式,最终也不会有足够的理解深度。
前面讨论了四则运算,也讨论了编译的整个步骤,这里对整个代码部分稍作了调整,可以方便大家更好地来理解。修改的主要也是main函数的部分,
代码地址,https://github.com/feixiaoxing/DIYCompiler/blob/master/day12/Parse.jj
- public static void main(String[] args) {
- for (String arg : args) {
- try {
- // generate syntax tree
- div_node div = evaluate(arg);
-
- // print tree
- System.out.println("");
- div.calculate_depth();
- div.print_node(div.get_depth(), div.get_depth()*5);
-
- // add semantic check
- System.out.println("\n\n");
- System.out.println(div.check_value());
-
- // generate intermediate code
- String str = div.generate_intermediate_code();
-
- // translate code
- str = translate_code(str);
-
- // optimise assemble code
- System.out.println("");
- System.out.println(optimise_assemble_code(str));
-
- } catch (ParseException ex) {
- System.err.println(ex.getMessage());
- }
- }
- }
全部的内容,大家可以参考github链接。这里只是把main函数中的函数调用了做了一个梳理。首先是调用evaluate生成语法树div_node,接着打印语法树,做好这些之后,就可以调用check_value做语义分析了。上面这些相当于编译的上半场。下半场就是,首先调用generate_intermediate_code生成中间代码,有中间代码接着就可以调用translate_code生成汇编代码,最后就是将生成的汇编代码通过函数optimise_assemble_code再优化一下。整个处理就是这么一个流程。
最后,我们将之前的blog链接都copy到这里,供大家学习的时候参考使用。