# 51.3.解析器阶段
这个分析阶段由两部分组成:
这个解析器定义于
克Y
和扫描L
是使用Unix工具bison和flex构建的。这个转化过程对解析器返回的数据结构进行修改和扩充。
# 51.3.1.解析器
解析器必须检查查询字符串(以纯文本形式到达)的有效语法。如果语法正确解析树建造并归还;否则将返回一个错误。解析器和lexer是使用著名的Unix工具bison和flex实现的。
这个雷克瑟是在文件中定义的扫描L
并负责识别标识符这个SQL关键字等等。对于找到的每个关键字或标识符代币生成并交给解析器。
解析器在文件中定义克Y
由一组语法规则和行动每当触发规则时都会执行。操作的代码(实际上是C代码)用于构建解析树。
档案扫描L
转换为C源文件扫描C
使用flex和克Y
转化为克C
使用野牛。在这些转换完成后,可以使用普通的C编译器来创建解析器。千万不要对生成的C文件做任何更改,因为下次调用flex或bison时它们会被覆盖。
# 笔记
上述转换和编译通常使用生成文件PostgreSQL源代码发行版附带。
对野牛或中给出的语法规则的详细描述克Y
将超出本手册的范围。有很多关于flex和bison的书籍和文件。你应该先熟悉bison,然后再开始学习中给出的语法克Y
否则你就不会明白那里发生了什么。
# 51.3.2.转化过程
解析器阶段仅使用有关SQL语法结构的固定规则创建解析树。它不会在系统目录中进行任何查找,因此不可能理解请求操作的详细语义。解析器完成后转化过程将解析器返回的树作为输入,并进行必要的语义解释,以了解查询引用了哪些表、函数和运算符。为表示此信息而构建的数据结构称为查询树.
将原始解析与语义分析分离的原因是,系统目录查找只能在事务中完成,我们不希望在收到查询字符串后立即启动事务。原始解析阶段足以识别事务控制命令(开始
, 回降
,等等),无需进一步分析即可正确执行。一旦我们知道我们正在处理一个实际的查询(例如选择
或使现代化
),如果我们还没有达成交易,就可以开始交易。只有这样才能调用转换过程。
转换过程创建的查询树在大多数地方在结构上与原始解析树相似,但在细节上有很多不同。例如,一个奉命
解析树中的节点表示语法上类似于函数调用的内容。这可能会转化为FuncExpr
或Aggref
节点,这取决于引用的名称是普通函数还是聚合函数。此外,有关列的实际数据类型和表达式结果的信息也会添加到查询树中。