【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);
	}
相關文章
相關標籤/搜索