我刚开始使用antlr 4,以前从来没有写过语法。语法似乎对短样本工作很好,但我有几个较长的例子,将运行一夜之间没有完成。我正在使用testg与我的输入文件。我使用了JVisualVM,并观察了代码在这里花费的大部分时间:
Org.antlr.v4.runtime.atn.ArrayPredictionContext.equals(Object) (89.8%)
Org.antlr.v4.runtime.atn.SingletonPredictionContext.equals(Object) (7.4%)
Org.antlr.v4.runtime.misc.DoubleKeyMap.put(Object,Object,Object) (1.8%)
Org.antlr.v4.runtime.misc.DoubleKeyMap.get(Object, Object) (0.9%)
问题似乎与以下格式的语句量有关。
reservedWord = quotedstring
在12到72之间出现问题
我给jvm 2G内存,它使用不到1G。堆会增大和缩小,所以我不认为有内存泄漏。
关于如何调试这样的东西有什么建议吗?
我没有看到附加文件的方法,堆栈跟踪是422行,大部分重复1278和1325。我不懂testig,所以我不知道它在做什么。如果我能找到,我会得到antlr-4.0-complete.jar的源代码。
at org.antlr.v4.runtime.atn.PredictionContext.hashCode(PredictionContext.java:121)
at org.antlr.v4.runtime.atn.SingletonPredictionContext.equals(SingletonPredictionContext.java:97)
at java.util.HashMap.getEntry(HashMap.java:349)
at java.util.LinkedHashMap.get(LinkedHashMap.java:280)
at org.antlr.v4.runtime.misc.DoubleKeyMap.get(DoubleKeyMap.java:60)
at org.antlr.v4.runtime.atn.PredictionContext.mergeSingletons(PredictionContext.java:204)
at org.antlr.v4.runtime.atn.PredictionContext.merge(PredictionContext.java:138)
at org.antlr.v4.runtime.atn.ATNConfigSet.add(ATNConfigSet.java:354)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1293)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1278)
<repeat a lot 1278 and 1325>
at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1325)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1278)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1325)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1278)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1261)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1325)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1278)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1261)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1325)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1278)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1325)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1278)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1261)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1325)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1278)
at org.antlr.v4.runtime.atn.ParserATNSimulator.closure(ParserATNSimulator.java:1216)
at org.antlr.v4.runtime.atn.ParserATNSimulator.computeReachSet(ParserATNSimulator.java:988)
at org.antlr.v4.runtime.atn.ParserATNSimulator.execATNWithFullContext(ParserATNSimulator.java:801)
at org.antlr.v4.runtime.atn.ParserATNSimulator.execATN(ParserATNSimulator.java:701)
at org.antlr.v4.runtime.atn.ParserATNSimulator.predictATN(ParserATNSimulator.java:389)
at org.antlr.v4.runtime.atn.ParserATNSimulator.adaptivePredict(ParserATNSimulator.java:346)
at ValidatingPolicyParser.showstatement(ValidatingPolicyParser.java:1023)
at ValidatingPolicyParser.statement(ValidatingPolicyParser.java:685)
at ValidatingPolicyParser.policy(ValidatingPolicyParser.java:246)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.antlr.v4.runtime.misc.TestRig.process(TestRig.java:247)
at org.antlr.v4.runtime.misc.TestRig.process(TestRig.java:209)
at org.antlr.v4.runtime.misc.TestRig.main(TestRig.java:142)
我开始编写一个精简的语法,用作测试用例。这个练习确实帮我找出了几个我从语法中删除的奇怪的地方。这解决了我修剪过的语法的问题,但是当我恢复完整的语法时,性能问题又出现了。
对我来说,增加一个简单比较的出现次数会非线性地增加处理时间,这真的很奇怪。一些'TOKEN = "SOMESTRING"或TOKEN = "SOMEOTHERSTING"'的实例处理起来相对较快,但如果我有75个这样的比较,处理时间就会变得太多了。
我无法确定antlr4源是否在某处可用。如果能逐步检查代码,看看发生了什么,那就太好了。
我想我会重复这个过程,看看结果如何。
那些计时数字没用。题目告诉你
相反,直接打断它。你会当场抓住它的。检查调用堆栈,并在必要时检查数据变量。如果你在那个时间点知道它在做什么,你就会知道问题出在哪里。
我发现我的语法有问题。经历了很多尝试和错误。我想知道在antlr4中是否使用了递归?