我正在尝试使用 ANTLR(尝试了 3.3 和 3.4)。当我尝试运行我的测试代码时会发生奇怪的事情。请先看我非常简单的代码,之后我会解释我的问题。
测试语法:
lexer grammar CSVLexer;
Comma
: ','
;
LineBreak
: '\r'? '\n'
| '\r'
;
SimpleValue
: ~(',' | '\r' | '\n' | '"')+
;
QuotedValue
: '"' ('""' | ~'"')* '"'
;
测试代码:
import org.antlr.runtime.*;
public class JMain {
public static void main(String[] args) throws Exception {
String source = "val1,val2,val3";
CSVLexer lexer = new CSVLexer(new ANTLRStringStream(source));
CommonTokenStream tokens = new CommonTokenStream(lexer);
int n = 1;
for (Object o : tokens.getTokens()) {
CommonToken token = (CommonToken) o;
System.out.println("token(" + n + ") = " + token.getText().replace("\n", "\\n"));
n++;
}
}
}
编译:
$ export CLASSPATH=antlr3.jar
$ java org.antlr.Tool CSVLexer.g
$ javac *.java
$ java JMain
第一个问题是它不打印任何东西:)。我在 Intellij IDEA (10) 工作,我试图从这里运行代码但没有成功(在 CLASSPATH 中使用 ANTLR)。但是,如果我将断点放在int i = 1
,调试并等待,比如说 1-3 秒再继续,它就可以了!如果我在没有断点的调试模式下运行它,它不会。有人可以向我解释可能是什么问题吗?谢谢你。
编辑:
所以我试着你放:
tokens.fill()
紧接着
CommonTokenStream tokens = new CommonTokenStream(lexer);
它奏效了。然而,随后我开始调试CommonTokenStream构造函数(几分钟),当我开始调试时,我得到tokens.fill()
了 IndexOutOfBoundException。所以不知何故在后台做了一些事情,但我在 IDEA 中看不到其他线程。
编辑2:
问题解决了。看来有必要先打电话fill()
,这BufferedTokenStream
可能不应该像这样使用。我遵循了本教程http://bkiers.blogspot.com/2011/03/2-introduction-to-antlr.html它可能对作者有用(我想知道为什么)。IntelliJ IDEA 调试器调用toString()
本地对象,然后调用它,fill()
这就是我设置断点时它工作的原因。toString()
修改状态是邪恶的!