PostgreSQL 源码解读(176)- 查询#94(语法分析:gram.y)#3

本节继续介绍PostgreSQL的语法分析定义文件gram.y的第三部分Productions(产生式).
Bison输入文件的组成:


%{
Declarations
%}
Definitions
%%
Productions
%%
User subroutines

一、Productions

Productions即产生式,这是用户编写的语法产生式,产生式的书写格式如下:


S -> X \n
X -> X + X | X - X | T_NUMBER

S -> X \n成为产生式,第一条产生式的最左边的符号成为起始符号,在这里是符号S.
为了避免出现递归解析,Bison因此会在最前面多添加一条产生式S’ -> S,S’为起始符号.
在Bison中,符号”:”表示一条”->”,同一个非终结符的不同产生式用”|”隔开,用”;”结束.每条产生式的后面花括号内是一段C代码,这些代码在该产生式被应用时执行,成为Action(动作),产生式的右边是ε(空集合)时,用注释/* empty */代替.
产生式中的非终结符不需要预先定义,Bison会自动根据所有产生式的左边符号来确定哪些符号是非终结符;终结符中,单字符token(token type值和字符的ASCII码相同)也不需要预先定义,在产生式内部直接用单引号括起来即可,其他类型的token则需要预先在 Definitions段中定义好,如%token ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER等,Bison会自动为这种token分配一个编号,再写到gram.h 文件中去,打开该文件,可以看到如下代码:


[root@localhost src]# vim ./include/parser/gram.h
...
/* Token type.  */
 44 #ifndef YYTOKENTYPE
 45 # define YYTOKENTYPE
 46   enum yytokentype
 47   {
 48     IDENT = 258,
 49     FCONST = 259,
 50     SCONST = 260,
 51     BCONST = 261,
 52     XCONST = 262,
 53     Op = 263,
 54     ICONST = 264,
 55     PARAM = 265,
 ....

编号从258开始,根据gram.y中的顺序逐个定义.


...
%token <str>    IDENT FCONST SCONST BCONST XCONST Op
%token <ival>    ICONST PARAM
%token            TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER
%token            LESS_EQUALS GREATER_EQUALS NOT_EQUALS
%token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
    AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
    ASSERTION ASSIGNMENT ASYMMETRIC AT ATTACH ATTRIBUTE AUTHORIZATION
...

这些token定义在scan.l中可直接使用.


#include "parser/gramparse.h" --> #include "parser/gram.h"

Bison会根据产生式以及符号优先级转化为LALR(1)动作表输出到gram.c文件中去.在gram.c文件中,PG根据自定义语法文件生成一个函数int base_yyparse (core_yyscan_t yyscanner);该函数按LR(1)解析流程对词法分析得到的token流进行解析,每当它需要读入下一个符号时,它就执行一次s = yylex() ,每当它要执行一个折叠(reduce)动作时,这个reduce所应用的产生式后面C代码将被执行,执行完后才将相应的状态出栈。
下面是gram.c中yyparse的部分代码:


/*----------.
| yyparse.  |
`----------*/
int
yyparse (core_yyscan_t yyscanner)
{
/* The lookahead symbol.  */
int yychar;
/* The semantic value o
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值