成功编译了openJDK后,才发现原来javac的这部分代码完全是由java语言实现的,所以可以把javac的代码单独提出来,放到eclipse里面,并且用eclipse编译和调试。这样真的超方便。。
刚开始做了一个很简单的修改,让java支持单引号的字符串(只作为练习)。思想很简单,找到Scanner的代码,把处理单引号的代码修改为处理双引号的代码即可。
过程如下:
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方法进入编译。
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方法,就是扫描下一个符合的方法。
4.进入com.sun.tools.javac.parser.Scanner.nextToken(),ctrl+F搜索 '\'' 找到处理单引号的代码。如下
01 | case '\'' : |
02 | scanChar(); |
03 | if (ch == '\'' ) { |
04 | lexError( "empty.char.lit" ); |
05 | } else { |
06 | if (ch == CR || ch == LF) |
07 | lexError(pos, "illegal.line.end.in.char.lit" ); |
08 | scanLitChar(); |
09 | if (ch == '\'' ) { |
10 | scanChar(); |
11 | token = CHARLITERAL; |
12 | } else { |
13 | lexError(pos, "unclosed.char.lit" ); |
14 | } |
15 | } |
16 | return ; |
这段代码下面就有处理双引号(也就是java里面真正支持的字符串)的代码,参照此代码,把处理单引号的代码修改成以下的即可:这是我修改后的代码:
01 | case '\'' : |
02 | scanChar(); |
03 | if (ch == '\'' ) { |
04 | lexError( "empty.char.lit" ); |
05 | } else { |
06 | if (ch == CR || ch == LF) |
07 | lexError(pos, "illegal.line.end.in.char.lit" ); |
08 | scanLitChar(); |
09 | if (ch == '\'' ) { |
10 | scanChar(); |
11 | token = CHARLITERAL; |
12 | } else { //////////what i add/////// |
13 | while (ch != '\'' && ch != CR && ch != LF && bp < buflen) |
14 | scanLitChar(); |
15 | if (ch == '\'' ) { |
16 | token = STRINGLITERAL; |
17 | scanChar(); |
18 | } else { |
19 | lexError(pos, "unclosed.str.lit" ); |
20 | } |
21 | |
22 | //lexError(pos, "unclosed.char.lit"); |
23 | } |
24 | } |
25 | return ; |
测试没有问题。。