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

早过忘川 提交于 2019-11-30 20:12:34

先把附件和测试文件发上来: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);
	}



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!