大四的毕业设计作的是,给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