在实际运行代码之前,可以使用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)
}
})
但是得到这个:
错误:注意:的超类包含以下名为语法错误的非最终成员:
答案 0 :(得分:1)
如果输入包含任何语法错误,这将在侦听器上调用visitErrorNode
方法。因此,如果您在侦听器中定义该方法,则会看到发生的任何错误。
如果侦听器直接执行代码(而不是先构建AST或其他形式的IR),则您可能不希望侦听器在出现语法错误时甚至开始执行。一种实现方法是将BailErrorStrategy而不是DefaultErrorStrategy设置为解析器的错误处理策略(在解析器上使用setErrorHandler
)。一旦发生语法错误,这将引发异常。
如果您不想中途遇到第一个错误,并且/或者除了语法错误之外,还希望进行其他检查(例如检查某些类型的语义错误),另一种方法是让侦听器仅执行这些检查。然后,仅当错误检查侦听器没有发现任何错误时,才运行代码执行侦听器。
答案 1 :(得分:0)
您在这里的位置正确。解析时,使用错误侦听器将错误存储在列表中。然后,您可以检查该列表。
但是,这要求解析过程中(例如,在解析侦听器中)除了与解析过程本身相关的内容外,不执行任何其他操作。任何后续操作(例如,编辑器中的错误标记)都应在解析运行后 完成。
如果您想查看使用此方法的应用程序示例,请查看IlSpy。它还演示了用于快速解析的两阶段解析策略。