【javac添加python 列表特性5】修改openJDK的Javac,使得支持List k...

先把附件和测试文件发上来: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);
	}
相关文章
相关标签/搜索