ANTLR4 性能的起点

Starting point for ANTLR4 performance

我已经迁移了一个相当大的 ANTLR2 grammar to 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 条规则,其中大部分时间都花在了上面,在这种情况下,这足以看到必须更改的内容(通过知道在哪里寻找问题)。