先把附件和测试文件发上来:Javac.rar (我使用的是JDK1.7) 前端
通过前一阶段的学习,对javac前端Parser阶段已经有了足够的理解,要使javac支持相似python的列表语法: java
List k=[1,'a',[2,3],"abc", new Object()]; python
这种语法的特征是: 学习
List 直接来源于java.util.*; 测试
初始化时使用的是[]; google
列表支持多种类型(基本和引用)混合; spa
支持列表的嵌套; code
实现 的想法是: 继承
Java里面已经有了以下能够支持的语法: token
List k=new ArrayList(Arrays.asList(1,'a',"abc"));
因此只须要在Parser阶段,在VariableInitilizer里面加上识别[]的语句,而且把后面[]的内容改为Java已经支持的语法:new ArrayList(Arrays.asList())便可。
实现的具体方法:
继承JavacParser类和Scanner类,以便进行扩展。
覆写JavacParser的 variableInitializer,若是有LBRACKET,则return listInitializer();
在listInitializer()里面能够先构造一段String newbuf="ArrayList(Arrays.asList('[]里面的内容'))"的代码,而后把当前Scanner的位置pos和串buf保存起来(用栈保存),让Scanner的pos和buf指向咱们新的pos=0,buf=newbuf。这样调用Scanner.nextToken的时候,就会直接去Scan添加的newbuf。最后返回一个creator。。
ListJavacParser extends JavacParser里面:
public JCExpression variableInitializer() { switch (S.token()) { case LBRACE: return arrayInitializer(S.pos(), null); case LBRACKET://处理方括号 return listInitializer(S.pos(),null); default: return parseExpression(); } } public JCExpression listInitializer(int newpos, JCExpression t) { accept(LBRACKET); ListScanner listScanner=(ListScanner)S; //Scanner char[] listStr=listString();//构造新的代码 listScanner.enterList(listStr);//保存Scanner的pos和buf,而且赋予新的pos=0,buf=listStr S.nextToken();//读取下一个符号 t=creator(S.pos(), null);//返回一个构造器 // accept(RBRACKET); listScanner.leaveList(); S.nextToken(); return t; private char[] listString() { int bracketNum=1; int bp1=S.pos(); while(S.token()!=SEMI) { if(S.token()==LBRACKET) bracketNum++; else if(S.token()==RBRACKET) bracketNum--; if(bracketNum==0) break; S.nextToken(); } if(bracketNum!=0) accept(RBRACKET); int bp2=S.pos(); String string=new String(S.getRawCharacters(bp1, bp2)); string ="ArrayList(Arrays.asList("+string+"));;"; return string.toCharArray(); } }
ListScanner extends Scanner里面:
private ArrayList<Object> oldBufs = new ArrayList<Object>(); public void enterList(char[] newBuf) {//保存buf和pos oldBufs.add(buf); oldBufs.add(sbuf); oldBufs.add(bp); oldBufs.add(pos); oldBufs.add(ch); buf = newBuf; bp = -1; ch=' '; } public void leaveList() {//回复buf和pos ch = (Character) oldBufs.remove(oldBufs.size() - 1); pos = (Integer) oldBufs.remove(oldBufs.size() - 1); bp = (Integer) oldBufs.remove(oldBufs.size() - 1); sbuf = (char[]) oldBufs.remove(oldBufs.size() - 1); buf = (char[]) oldBufs.remove(oldBufs.size() - 1); }