先把附件和测试文件发上来:Javac.rar (我使用的是JDK1.7)
经过前一阶段的学习,对javac前端Parser阶段已经有了足够的理解,要使javac支持类似python的列表语法:
List k=[1,'a',[2,3],"abc", new Object()];
这种语法的特征是:
List 直接来源于java.util.*;
初始化时使用的是[];
列表支持多种类型(基本和引用)混合;
支持列表的嵌套;
实现 的想法是:
Java里面已经有了如下可以支持的语法:
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);
}
来源:oschina
链接:https://my.oschina.net/u/574785/blog/90363