在学习Antlr的过程中,遇到了一个问题,花了好几天的时间才弄明白原因,所以写出来和大家共享一下。问题是:在.g的文件中加入一个输出语句,如图中所示。
本来的目标是想在DOS命令下,测试Antlr通过debug命令生成的__Test__.java文件,使其执行上图中所示的输出语句,即输入"int x;",想得到的输出是“int”,但是一直无法实现(在Antlr中可以实现)。
于是就开始分析原因:
我一开始使用的代码都是在debug模式下生成的,如图所示(绿色的甲壳虫),通过分析代码发现,在这种模式下生成的CminusParser.java文件里边的构造方法,如下所示:
而自动生成的测试文件__Test__.java中,调用CminusParser.java中的构造方法如下图所示:
发现了这一细节后,我有采用别的方式来生成代码,使用antlr的Generate –》Generate Code命令生成代码,发现CminusParser.java文件里边的构造方法,如下所示:
自己写的测试类中,调用CminusParser.java中的构造方法如下所示:
CminusParser g = new CminusParser(tokens);
最后测试通过了,原来是因为在两种方式下生成代码的构造方法的参数不一样。我只是发现了问题所在,但是具体的原理还没有搞明白,希望高手不吝赐教。
__Test__.java的代码如下:
import java.io.*;
import org.antlr.runtime.*;
import org.antlr.runtime.debug.DebugEventSocketProxy;
public class __Test__ {
public static void main(String args[]) throws Exception {
CminusLexer lex = new CminusLexer(new ANTLRFileStream("F:\\antlr\\output\\__Test___input.txt", "UTF8"));
CommonTokenStream tokens = new CommonTokenStream(lex);
CminusParser g = new CminusParser(tokens, 49100, null);
try {
g.program();
} catch (RecognitionException e) {
e.printStackTrace();
}
}
}
Test.java的代码如下:
import java.io.*;
import org.antlr.runtime.*;
public class Test {
public static void main(String[] args) {
CminusLexer lex = new CminusLexer(new ANTLRStringStream("int a;"));
CommonTokenStream tokens = new CommonTokenStream(lex);
CminusParser g = new CminusParser(tokens);
try {
g.program();
} catch (Exception e) {
e.printStackTrace();
}
}
}