我已经将一个相当大的ANTLR2语法迁移到ANTLR4,并且达到了两个语法的输出几乎相同的步骤,除了一些边缘情况。但是,有些文件非常长,无法解析(即使使用SLL预测模式和BailOutStrategy(,因此我想知道如何找到应该首先修复哪些规则。
我已经使用 Parser#setProfile(( 收集了一些统计信息,但我不知道如何解释每个 DecisionInfo 对象中的结果。有没有关于如何开始优化大型 ANTLR4 语法并找到先追逐哪只兔子的好文档?
由于我不知道在 DecisionInfo 对象中查找什么,这是我发现的,并帮助我将解析时间至少缩短了一个数量级。
首先,我使用org.antlr.v4.runtime.Parser.setProfile(boolean profile)
对语法进行了分析,然后对数千个文件执行了org.antlr.v4.runtime.Parser.getInterpreter().setPredictionMode(PredictionMode.SLL)
的解析器,并浏览了预测时间最长的规则:
Arrays.stream(parser.getParseInfo().getDecisionInfo())
.filter(decision -> decision.timeInPrediction > 100000000)
.sorted((d1, d2) -> Long.compare(d2.timeInPrediction, d1.timeInPrediction))
.forEach(decision -> System.out.println(
String.format("Time: %d in %d calls - LL_Lookaheads: %d Max k: %d Ambiguities: %d Errors: %d Rule: %s",
decision.timeInPrediction / 1000000,
decision.invocations, decision.SLL_TotalLook,
decision.SLL_MaxLook, decision.ambiguities.size(),
decision.errors.size(), Proparse.ruleNames[Proparse._ATN.getDecisionState(decision.decision).ruleIndex])))
然后在最高最大展望时使用相同的 lamba 进行展望,但以下情况除外:
filter(decision -> decision.SLL_MaxLook > 50).sorted((d1, d2) -> Long.compare(d2.SLL_MaxLook, d1.SLL_MaxLook))
这给了我 4 条规则,其中大部分时间都花在了这些规则上,在这种情况下,这足以看到必须更改的内容(通过知道在哪里寻找问题(。