使用 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 阶段解析策略。
我可以在实际 运行 代码之前使用 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 阶段解析策略。