2

我正在为 C++ 中的 SQL select 语句编写(手写)递归下降解析器,我需要知道我创建的解析树是否正确。我想检查一下,但我没有得到很好的 sql 解析树来源。我的方法是 - 为每个产品编写一个函数,并在该函数中将结果添加到根树中。谁能帮我?提前致谢。

4

3 回答 3

2

我不知道您将如何验证您的代码是否正确,但如果您担心自己对 SQL 语法的理解,那么这里有一个网站列出了各种 SQL 方言的 BNF 语法。您应该能够根据这些规则构建您的解析器。

于 2010-10-14T07:48:08.323 回答
2

我的公司构建了很多解析器,并且遇到了同样的问题。我们最近完成了基于草案标准的 SQL 2011 解析器。

您几乎可以通过手动检查许多源代码案例来确定解析树是否正确。这假定您可以以易于检查的形式打印解析树;这很容易通过解析树的递归树遍历来完成。[您必须已经相信您的抽象语法树节点正确地模拟了您打算捕获的内容!]。您仔细选择案例以练习语法的不同部分(想想“语法单元测试”)。对于像 SQL 这样丰富的语言来说,这是一项艰巨的工作。

您还需要验证解析器是否正常工作,为此您需要为您正在处理的特定 SQL 方言提供大量真实代码。我通常会尝试找到 100K-1M 的 SLOC,如果解析器不能吃掉所有这些,我还有工作要做。一旦达到该级别,您就会认为您的解析器正常,并将进一步的错误视为“维护问题”。

虽然以下内容可能不会直接帮助您,但它可能会暗示您可以前进的方向。基于拥有极其强大的解析机制,我使用了一种稍微不同的方法。我们的工具DMS Software Reengineering Toolkit给定一个语法,将自动生成 AST,并具有打印此类解析树的内置工具(以 XML 的一种形式)。AST 有足够的信息来重新生成(“漂亮打印”)源文本,而 DMS 有一个内置的漂亮打印机。因此,在手动检查了各种案例之后,我所做的是获取大量代码,并为每个文件解析它(由于上面所做的工作而没有解析错误),漂亮地打印源代码,然后重新解析源(期望没有错误)。这是一个强有力的暗示,表明我们在往返过程中没有丢失任何东西。

我们有一个可用的新工具,Smart Differencer,它可以比较两个程序的文本,看看它们是否“相同”,忽略语言布局规则。它本质上通过解析两个文件并比较它们的解析树来工作,忽略格式(行/列/转义/基数/注释/空白)。我们开始做的是解析源代码,对它进行漂亮打印,然后将漂亮打印的结果与原始文件进行智能比较。SmartDiff 应该说“没有 AST 差异”。这是一个更强有力的暗示,我们没有失去任何东西。如果您愿意比较打印前后的解析树,您可以做几乎相同的事情。

于 2010-10-15T16:37:24.587 回答
0

这个基于 pyparsing 的解析器作为第二个 SELECT 解析资源可能会有所帮助(尽管它是在 Python 中,而不是 C++ 中,抱歉)。

于 2010-10-15T04:53:37.963 回答