先把附件和測試文件發上來: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); }