修改openJDK7的javac,使得java支持单引号字符串

19 篇文章 0 订阅

大四的毕业设计做的是,给java语言增加一些特性(比如python的列表和字典结构)。涉及到javac编译器前端(scanner,parser)的修改。现在才刚开始着手。。

成功编译了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;
这样,如果一个单引号的字符串,它的长度为1,那么javac会把它当做字符。而如果长度大于1,就会当做字符串处理。

测试没有问题。。

转自:http://my.oschina.net/superpdm/blog/87235?from=20121111

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值