我已经将相当大的ANTLR2 grammar迁移到ANTLR4,并达到了一个步骤,除了少数情况外,两个语法的输出几乎相同。但是,有些文件解析太长(即使使用SLL预测模式和BailOutStrategy),所以我想知道如何找到应该首先修复的规则。
我已经使用Parser#setProfile()收集了一些统计信息,但是我不知道如何解释每个DecisionInfo对象中的结果。是否有关于如何开始优化大型ANTLR4语法并找到首先追逐哪只兔子的良好文档?
答案 0 :(得分:0)
由于我不知道在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])))
,然后使用相同的兰巴以最大的最大前瞻方式进行操作,除了:
filter(decision -> decision.SLL_MaxLook > 50).sorted((d1, d2) -> Long.compare(d2.SLL_MaxLook, d1.SLL_MaxLook))
这给了我4条规则,这些规则大部分时间都花在了哪里,在这种情况下,这足以了解必须更改的内容(通过知道在哪里寻找问题)。