前面几篇提到的一些特性,都是经过把特殊的新语法,翻译成java能够支持的语法来实现的。javac编译一个文件的过程为:(参见javac编译文件过程) java
Scanner->Parser->Annotation(optional)->Enter->Attribute->Flow->Desugar->Generate express
那么以前个人工做都是集中在Parser和Attribute上面的。添加新语法的时候,就是把Parser修改一下,使其可以识别新语法为一个新的节点,而后Annotation,Enter,Attribute基本不变,在Attribute事后能够得到类型等额外信息,而后对这个时候的AST运用一个Translator,把新语法转变为旧的语法。所以Flow和之后的过程都没有任何改变。 spa
而此次是涉及到全过程的改变。此次我想实现的是这样的语法: .net
int r1=10,r2=100; double area; double sum={double PI=Math.PI; area=PI*r1*r1;} + {double PI=Math.PI; area=PI*r2*r2;};其实就是把Block做为一个能够有值的结构,他的值就是block最后一个语句的值。block依然是原来的功能,能够有任何的语句,block的结果也能够参与运算。
只是这是一个实实在在的新语法,不能经过翻译来解决问题。实现的方法其实没有我想象中那么难。 翻译
1.添加新的语法节点JCBlockExp,里面的成员就一个JCBlock。 调试
2.修改visitor和visitor子类的定义,在里面加入一个visitBlockExp,添加的内容参照JCBlock,也就是至关于BlockExp只是一个包装,而实际上仍是处理它的成员JCBlock。因此虽然要改不少文件,但基本是参照JCBlock的代码写过来的 code
3.修改Parser使其接受新的语法节点。将JCBlockExp做为一个term3. blog
4.修改Attribute中的visitBlockExp,把原本的result=null,仿照成其余expression的处理的结尾,变成result=check(...) get
5.修改Generate中的visitBlockExp,原本block中全部的语句都是用genStat来生成代码的,而我只须要把最后一条语句用genExp来生成,前面的语句都不变 it
调试调试应该就能够了