使用 antlr v4 进行语法检查

Use antlr v4 for syntax check

我可以在实际 运行 代码之前使用 antlr v4 进行语法检查吗?

示例:
我定义了语法:select * from table,我想在实际执行之前知道该语句是否正确。

以下是我的代码:

val listener = new SQLListener()
val loadLexer = new SQLLexer(new ANTLRInputStream(input))  
val tokens = new CommonTokenStream(loadLexer) 
val parser = new SQLParser(tokens)
val stat = parser.statement()

我试过了,但 DefaultErrorStrategy 不会抛出异常

我试过这个:

parser.addErrorListener(new BaseErrorListener {
  override def syntaxError(recognizer: Recognizer[_, _ <: ATNSimulator],
                           offendingSymbol: scala.Any,
                           line: Int,
                           charPositionInLine: Int,
                           msg: String, e: RecognitionException ): Unit =  {
    println("==========2============"+msg)
    throw new AssertionError("line: " + line + ", offset: " + charPositionInLine +
      ", symbol:" + offendingSymbol + " " + msg)
  }
})   

但是得到这个:

Error: Note: the super classes of contain the following, non final members named syntaxError:

如果输入包含任何语法错误,这将在侦听器上调用 visitErrorNode 方法。因此,如果您在侦听器中定义该方法,您将看到发生的任何错误。

如果您的侦听器直接执行代码(而不是首先构建 AST 或其他形式的 IR),您可能不希望您的侦听器在出现语法错误时甚至开始执行。实现这一点的一种方法是将 BailErrorStrategy 而不是 DefaultErrorStrategy 设置为解析器的错误处理策略(在解析器上使用 setErrorHandler )。这将在出现语法错误时立即抛出异常。

如果您不想在遇到第一个错误时中止 and/or,您需要一些额外的检查,而不仅仅是语法错误(例如检查某些类型的语义错误),另一种方法是让侦听器只执行这些检查。然后,只有当错误检查侦听器没有发现任何错误时,您才会 运行 您的代码执行侦听器。

你走在正确的轨道上。在解析时使用错误侦听器将错误存储在列表中。之后您可以检查该列表。

然而,除了与解析过程本身相关的内容之外,这要求在解析过程中(例如在解析侦听器中)不执行任何操作。任何后续操作(例如编辑器中的错误标记)都应该在 解析 运行.

之后完成

如果您想查看使用此方法的应用程序示例,请查看 parser module implementation of MySQL Workbench。它还演示了用于更快解析的 2 阶段解析策略。