第一次机会 NoViableAltException 减慢调试速度

Posted

技术标签:

【中文标题】第一次机会 NoViableAltException 减慢调试速度【英文标题】:First chance NoViableAltException slows down debugging 【发布时间】:2014-02-26 17:56:36 【问题描述】:

我们将antlr用于数据点的层次结构,可以相互计算,其中计算用公式表示。 假设我们有来自外部测量系统的基础数据点 a1 和 a2。 然后我们可以定义一个数据点 b 计算为 a1 和 a2 的总和,通过公式 “a1 + a2”。 到目前为止一切正常,但问题是,antlr 似乎在通过抛出、捕获和重新抛出 NoViableAltException 进行解析时回溯错误的分支。 我们使用来自 Sam Harwell 的 Antlr 的 C# 端口并将其与 C# 一起使用,并在 VStudio 2012 中调试。 Visual Studio 捕获并显示第一次机会异常,这是一个相当缓慢的过程。 即使在调试器窗口中选择不显示第一次机会异常,它们仍然会被捕获并减慢调试器的速度。 由于有数百个由公式定义的数据点,这些第一次机会异常使调试非常非常缓慢。 我的问题是:有没有办法改进语法以减少第一次出现 NoViableAltException 的机会? 或者改变antlr代码,通过返回值实现回溯而不是抛出/捕获NoViableAltException是否有意义?

【问题讨论】:

我不是 antlr 用户,但这些异常是否发生在您的代码或库中? 它们出现在库和 antlr 根据我的语法自动生成的代码中。 【参考方案1】:

我不确定 ANTLR 3 在 backtrack=true 选项下的表现如何,因为我个人从未在生产中使用过该构造。

如果可以,您应该考虑updating to ANTLR 4,它不需要对长前瞻序列进行回溯(事实上,ANTLR 4 中没有backtrack 选项)。

否则,您应该更新语法以在成功解析输入的同时删除backtrack=true 选项。即使在调试器之外,这也将显着提高解析器的性能。

backtrack=true 选项应仅被视为实验选项。它对生产代码的影响很大,并且经常导致不可预测和/或无法解释的行为。

【讨论】:

我没有明确设置 backtrack=true 选项。可能是我错误地使用了回溯一词。无论如何,在解析过程中有很多第一次机会 NoViableAltException 抛出。这是 antlr 的正常行为还是语法有问题? 这意味着语法不是您输入的正确表示,反之亦然。如果您更正语法或语法错误,它将停止抛出异常。 感谢您的回复。我一直认为这个异常是解析过程中的一个常规机制,所以没有检查它是否与输入表达式的某个部分有关。 好吧,现在我重新检查,发现它与在输入中附加EOF(0xffff)有关。我认为解析器有必要知道要停止。我的语法中也有 EOF,但在词法分析器文件中没有,因为它是由 antlr 自动添加到生成的词法分析器代码中的。它在语法中是 antlr2 的某种遗留物。无论如何,我停止附加 EOF,现在不再有例外。非常感谢。

以上是关于第一次机会 NoViableAltException 减慢调试速度的主要内容,如果未能解决你的问题,请参考以下文章

为啥我没有获得第一次机会异常的转储文件

暂时禁用第一次机会异常

一次机会游戏怎么设置中文

防止输出窗口中的第一次机会异常

第一次机会例外

第一次机会异常访问路径被拒绝 (UnauthorizedAccessException)