大四的畢業設計作的是,給java語言增長一些特性(好比python的列表和字典結構)。涉及到javac編譯器前端(scanner,parser)的修改。如今纔剛開始着手。。 前端
成功編譯了openJDK後,才發現原來javac的這部分代碼徹底是由java語言實現的,因此能夠把javac的代碼單獨提出來,放到eclipse裏面,而且用eclipse編譯和調試。這樣真的超方便。。 java
剛開始作了一個很簡單的修改,讓java支持單引號的字符串(只做爲練習)。思想很簡單,找到Scanner的代碼,把處理單引號的代碼修改成處理雙引號的代碼便可。 python
過程以下: eclipse
1.eclipse中新建一個工程。而後把openJDK7裏面目錄:openjdk7\langtools\src\share\classes\com,所有導入到eclipse中,運行。可能會遇到一個版本的問題,就是編譯時的javac版本和eclipse環境中,配置Preferences->compiler 和Preferences->buildpath兩個裏面的版本一致便可。能夠生成javac,測試沒有問題。。 測試
2.進入com.sun.tools.javac.Main,裏面有一個main方法就是javac最外層的調用。它調用了com.sun.tools.javac.main.Main的compile方法進入編譯。 ui
3.單步跟蹤,找到真正scanner和parser的位置。前面調用幾個類大體以下:com.sun.tools.javac.Main->com.sun.tools.javac.main.Main->com.sun.tools.javac.main.JavaCompiler->com.sun.tools.javac.parser.JavacParser->com.sun.tools.javac.parser.Scanner. 最後能夠發現Scanner的nextToken方法,就是掃描下一個符合的方法。 spa
4.進入com.sun.tools.javac.parser.Scanner.nextToken(),ctrl+F搜索 '\'' 找處處理單引號的代碼。以下 設計
case '\'': scanChar(); if (ch == '\'') { lexError("empty.char.lit"); } else { if (ch == CR || ch == LF) lexError(pos, "illegal.line.end.in.char.lit"); scanLitChar(); if (ch == '\'') { scanChar(); token = CHARLITERAL; } else { lexError(pos, "unclosed.char.lit"); } } return;
這段代碼下面就有處理雙引號(也就是java裏面真正支持的字符串)的代碼,參照此代碼,把處理單引號的代碼修改爲如下的便可:這是我修改後的代碼: 調試
case '\'': scanChar(); if (ch == '\'') { lexError("empty.char.lit"); } else { if (ch == CR || ch == LF) lexError(pos, "illegal.line.end.in.char.lit"); scanLitChar(); if (ch == '\'') { scanChar(); token = CHARLITERAL; } else {//////////what i add/////// while (ch != '\'' && ch != CR && ch != LF && bp < buflen) scanLitChar(); if (ch == '\'') { token = STRINGLITERAL; scanChar(); } else { lexError(pos, "unclosed.str.lit"); } //lexError(pos, "unclosed.char.lit"); } } return;這樣,若是一個單引號的字符串,它的長度爲1,那麼javac會把它當作字符。而若是長度大於1,就會當作字符串處理。
測試沒有問題。。 code