支持的版本:当前 (17) / 16 / 15 / 14 / 13
开发版本:devel
不支持的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

50.3. 解析器阶段 #

解析器阶段由两个部分组成

  • gram.yscan.l 中定义的解析器是使用 Unix 工具 bisonflex 构建的。

  • 转换过程 对解析器返回的数据结构进行修改和增强。

50.3.1. 解析器 #

解析器必须检查查询字符串(以纯文本形式到达)是否具有有效的语法。如果语法正确,则会构建并返回一个解析树;否则将返回一个错误。解析器和词法分析器是使用众所周知的 Unix 工具 bisonflex 实现的。

词法分析器定义在 scan.l 文件中,负责识别标识符SQL 关键字等。对于找到的每个关键字或标识符,都会生成一个令牌并将其传递给解析器。

解析器定义在 gram.y 文件中,由一组语法规则动作组成,每当触发规则时都会执行这些动作。动作的代码(实际上是 C 代码)用于构建解析树。

文件 scan.l 使用程序 flex 转换为 C 源文件 scan.c,而 gram.y 使用 bison 转换为 gram.c。完成这些转换后,可以使用普通的 C 编译器来创建解析器。切勿对生成的 C 文件进行任何更改,因为下次调用 flexbison 时它们将被覆盖。

注意

所提到的转换和编译通常是使用 PostgreSQL 源代码发行版附带的makefile自动完成的。

详细描述 bisongram.y 中给出的语法规则将超出本手册的范围。有许多书籍和文档涉及 flexbison。在开始研究 gram.y 中给出的语法之前,您应该熟悉 bison,否则您将无法理解那里发生的事情。

50.3.2. 转换过程 #

解析器阶段仅使用有关 SQL 句法结构的固定规则来创建解析树。它不会在系统目录中进行任何查找,因此无法理解所请求操作的详细语义。解析器完成后,转换过程 将解析器返回的树作为输入,并进行语义解释,以理解查询引用了哪些表、函数和运算符。为表示此信息而构建的数据结构称为查询树

将原始解析与语义分析分开的原因是,系统目录查找只能在事务中完成,并且我们不希望在收到查询字符串后立即启动事务。原始解析阶段足以识别事务控制命令(BEGINROLLBACK 等),然后可以正确执行这些命令,而无需进一步分析。一旦我们知道我们正在处理实际查询(例如 SELECTUPDATE),如果我们尚未处于事务中,则可以开始一个事务。只有这样才能调用转换过程。

转换过程创建的查询树在大多数地方与原始解析树在结构上相似,但细节上有很多差异。例如,解析树中的 FuncCall 节点表示在语法上看起来像函数调用的内容。这可能会转换为 FuncExprAggref 节点,具体取决于引用的名称是否为普通函数或聚合函数。此外,有关列和表达式结果的实际数据类型的信息将添加到查询树中。

提交更正

如果您在文档中发现任何不正确、与您使用特定功能的经验不符或需要进一步澄清的内容,请使用此表格报告文档问题。