使用Antlr v4进行语法检查

时间:2018-07-26 07:32:02

标签: antlr antlr4

在实际运行代码之前,可以使用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)
  }
})   

但是得到这个:

  

错误:注意:的超类包含以下名为语法错误的非最终成员:

2 个答案:

答案 0 :(得分:1)

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

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

如果您不想中途遇到第一个错误,并且/或者除了语法错误之外,还希望进行其他检查(例如检查某些类型的语义错误),另一种方法是让侦听器仅执行这些检查。然后,仅当错误检查侦听器没有发现任何错误时,才运行代码执行侦听器。

答案 1 :(得分:0)

您在这里的位置正确。解析时,使用错误侦听器将错误存储在列表中。然后,您可以检查该列表。

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

如果您想查看使用此方法的应用程序示例,请查看IlSpy。它还演示了用于快速解析的两阶段解析策略。