当前位置: 首页 > 面试题库 >

在Java和ANTLRWorks调试器中捕获ANTLR的NoViableAltException

公西志文
2023-03-14
问题内容

考虑一下,我们尝试将一些不正确的输入文本提供给某种语法(例如,包含一些未知标记的文本)。在ANTLRWorks解释过程中,我们将NoViableAltException在图中看到。

UPD: 在两种情况下会出现此异常:

1)意外使用某些已知令牌,在这种情况下,我们将收到类似 line 5:36 no viable alternative at input ','

2)使用未知令牌类型。例如,语法对以@符号开头的标记一无所知。而且我们正在尝试将带有这种标记的文本提供给我们的语法。

不幸的是, 在情况(2) 中,ANTLRWorks调试器和生成的Java代码 均未引发该异常
;但是只能在ANTLRWorks解释器的结果图中看到。

我还尝试将以下标准代码添加到语法中:

@parser::members {
    private IErrorReporter errorReporter = null;
    public void setErrorReporter(IErrorReporter errorReporter) {
        this.errorReporter = errorReporter;
    }
    public void emitErrorMessage(String msg) {
        errorReporter.reportError(msg);
    }
}
@lexer::members {
    ... the same code as above ...
}

此构造成功捕获类型(1)的解析错误(例如,有关令牌意外使用的错误:)line 5:36 no viable alternative at input ','。但是,如果输入不可行且令牌未知,则解析器仅children == null在顶级CommonTree对象中生成,而不会报告任何错误。

我正在使用antlr 3.5

问题:是否有可能NoViableAltException在生成的Java代码中陷入描述的情况?


问题答案:

好吧,280Z28对这个问题的第二部分给出的答案很好地解决了这两个问题。因此,这是正确的答案。
当词法分析器包含可以匹配空字符串的规则时,通常会发生这种情况。例如,考虑以下规则:

WS : (' ' | '\t')*;

该规则可以创建一个WS令牌,该令牌总共包含0个空格和/或制表符,这意味着在您输入的任何其他令牌之间可以有无限多个。在涉及无效输入的某些情况下,错误恢复过程可能被强制进入无限循环,该循环将缓冲令牌,直到Java用尽内存。

解决这种情况的第一步是检查每个词法分析器规则,以确保不会发生这种情况。所述WS应该代替这样写,以确保至少1空间和/或制表符被消耗。

WS : (' ' | '\t')+;

PS:ANTLR 4对语法执行静态检查,如果发生错误,将产生错误(4.0)或警告(4.0.1+)。



 类似资料:
  • 假设我们试图将一些不正确的输入文本输入到某个语法中(例如,包含一些未知标记的文本)。在中,在解释过程中,我们将在graph中看到。 UPD:出现此异常有两种情况: 我还尝试在语法中添加以下标准代码: 此构造成功地捕获了类型(1)的解析错误(例如,关于意外使用令牌的错误:)。但是,如果不可行输入带有未知标记,解析器只在顶部对象中生成,而不报告任何错误。 我使用的是。

  • 我在运行python flask web应用程序时得到了这个回溯(最近一次调用是最后一次)。 从烧瓶导入烧瓶app=烧瓶(名称) @app.route ("/") def你好():返回" 我正在终端上运行服务器:“cd Flask\u Blog”,“export Flask\u DEBUG=1” 我也尝试初始化烧瓶模块分配"flask.init()"代码,但我仍然得到错误的网页浏览器! 我做错什么

  • 问题内容: 您可以尝试/捕获Java中的堆栈溢出异常吗?它似乎在向任一方向投掷自己。当程序溢出时,我想“惩罚”该值。 问题答案: 似乎可以工作:

  • 我有shell文件(deploy.sh)执行以下命令: 当其中一个命令发生错误时,我想停止bash的执行。 shell中的哪个命令可以做到这一点?

  • 我试图创建一个测试来验证我的代码(见下面的伪代码)是否正确捕获异常。我知道JUnit能够测试代码是否用以下代码抛出异常: 然而,我正在测试的软件的原始代码捕获了这个异常并打印了一条消息 JUnit是否有办法验证此消息?或者我应该改变一下我的流行语? 注:我已阅读,我应使用以下内容: 但是程序崩溃,因为它无法识别对象。 我尝试测试的方法的伪代码(出于隐私原因,不要发布确切的内容):

  • 我有一个存储过程似乎没有正确记录错误。 代码有错误,但 catch 块似乎未生效。 try块相当长,但错误部分很简单,并且在最后出现,所以我已经对此进行了预测。 proc失败的错误是我们的老朋友“列名或提供的值的数量与表定义不匹配”。我已经修复了这个错误 - 这是一个愚蠢的懒惰错误 - 但我感到困惑为什么我的错误日志记录过程似乎没有工作 - 没有行入到我的 ExtractsErrorLog 表中。