当前位置: 首页 > 知识库问答 >
问题:

ANTLR4 Lexer错误报告(违规字符的长度)

景景胜
2023-03-14

我正在为使用ANTLR4的某种语言开发一个小型IDE,当lexer无法匹配错误字符时,我需要在错误字符下划线。在这种情况下,内置的org.antlr.v4.runtime.antlrerrorlistener实现向stderr输出一条消息,类似于如下所示:

line 35:25 token recognition error at: 'foo\n'

我完全可以理解如何获得关于错误的行和列的信息(作为参数传递给SyntaxError回调),但如何在回调中获得'foo\n'字符串?

当解析器是错误的来源时,它会将违规令牌作为syntaxerror回调的第二个参数传递,因此提取关于错误输入的开始和停止偏移量的信息变得很简单,参考书中也对此进行了解释。但是当来源是一个lexer的情况下呢?在本例中,回调中的第二个参数为null,这可能是因为lexer未能形成令牌。

我需要不匹配字符的长度来知道下划线的大小,但是在调试我的侦听器实现时,我在提供的回调参数中找不到这个信息(除了通过字符串操作从提供的错误消息中提取它,这将是错误的)。'foo\n'字符串显然是以某种方式获得的,那么我遗漏了什么呢?

我怀疑我可能找错了地方,我应该考虑扩展DefaultErrorStrategy,以便形成错误消息。

共有1个答案

秦承允
2023-03-14

您应该在编写lexer时避免出现语法错误。在ANTLR4中,只需添加以下作为lexer的最后一条规则,就可以很容易地做到这一点:

ErrorChar : . ;

通过这样做,您的错误将从lexer移到解析器。

在某些情况下,当用户在IDE中编辑代码时,您可以采取其他步骤来帮助他们。例如,假设您的语言支持以下形式的双引号字符串,这些字符串不能跨多行:

StringLiteral : '"' ~[\r\n"]* '"';
StringLiteral : '"' ~[\r\n"]* '"';
UnterminatedStringLiteral : '"' ~[\r\n"]*;

然后可以重写emit()方法,以特殊方式处理UnterminatedStringLiteral。结果,用户会看到一个很大的错误消息,解析器会看到一个它通常可以很好处理的stringliteral标记。

@Override
public Token emit() {
    switch (getType()) {
    case UnterminatedStringLiteral:
        setType(StringLiteral);
        Token result = super.emit();
        // you'll need to define this method
        reportError(result, "Unterminated string literal");
        return result;
    default:
        return super.emit();
    }
}
 类似资料:
  • 我设置了一个作业来在Reports\pep8.log中查找pep8.log文件 但当我运行该作业时,我发现违规插件查找报告的路径没有意义: 生成的xml文件:C:\jenkins\jobs\python-template-2\workspace\reports\pep8.log=============================================================

  • 错误日志对于发现程序中的错误是非常有帮助的,但是有些时候它也会将应用程序的结构暴露给外部。为了有效的保护你的应用程序不受到由此而引发的问题。你需要将在你的服务器上使用开发和生产(线上)两套不同的配置。 开发环境 为了在开发环境中显示所有可能的错误,将你的 php.ini 进行如下配置: display_errors = On display_startup_errors = On error_re

  • 1.1.2. 错误报告 没有不会犯错的开发者,PHP的错误报告功能将协助您确认和定位这些错误。可以PHP提供的这些详细描述也可能被恶意攻击者看到,这就不妙了。使大众看不到报错信息,这一点很重要。做到这一点很容易,只要关闭display_errors,当然如果您希望得到出错信息,可以打开log_errors选项,并在error_log选项中设置出错日志文件的保存路径。 由于出错报告的级别设定可以导致

  • 当简单报表不适用于子报表时,此操作有效...

  • 需知 当你觉得发现了一个Swoole内核的bug时,请提出报告。 Swoole的内核开发者们或许还不知道问题的存在, 除非你主动提出报告,否则BUG也许将很难被发现并修复, 你可以在 Github的issue区 提出错误报告(即点击右上角绿色的New issue按钮),这里的错误报告将会被最优先解决。 请不要在邮件列表或私人信件中发送错误报告,Github的issue区同样可以提出对于Swoole

  • 错误报告 Stylus内置梦幻般的错误报告,针对语法、解析以及计算错误,完整的堆栈跟踪,行号和文件名。 解析错误 解析错误例子: body form input == padding 5px 呈现为: Error: /Users/tj/Projects/stylus/testing/test.styl:4 3: ' form input' 4: ' == padding