阅读该文章需要有一定的语法知识:
冒号前面的只能是非终结符,用$$表示
冒号后面的标识符,可以是终结符也可以是非终结符。用$n表示。n从1开始递增。当匹配了冒号后面的语法后,就会运行{}里面的操作语句。
PG语法

对应gram.y中的语法

其中
$$表示在冒号前面,表示该语法最终的生成结果,可以是任意类型,该语法中表示结构体:CreateFunctionStmt。
$1表示冒号后的第一个标识符,表示终结符 CREATE
$2 表示冒号后的第二个标识符,代表非终结符 opt_or_replace
$3 表示冒号后的第三个标识符,代表终结符 FUNCTION
同理,$n也可以表示任意类型。
上文中的$2表示的opt_or_replace又可以构成下面的语法:

其中opt_or_replace 用$$表示,'|'(竖线) 表示或的意思,表示opt_or_replace可以匹配下面的两种情况
表示opt_or_replace可以匹配OR REPLACE,当匹配到OR REPLACE语法时,$$被赋值为true,也就是说此时opt_or_replace的值是true
表示opt_or_replace匹配一个空,也就是没有任何标识符,此时,$$被赋值为false,所以该情况下opt_or_replace赋值为false。
流程表示:
当走到语法分析模块时,系统根据输入的字符串逐个扫描,当扫描到[CREATE]关键字时,因为该关键字没有对应的操作。所以继续扫描。
当扫描[opt_or_replace]关键字时,发下该关键字是非终结符。然后跳到[opt_or_replace]对应的语法中继续扫描。当扫描到[OR REPLACE]时,系统发现该语法可以规约到[opt_or_replace]非终结符上,于是执行{}里面的操作{ $$ = true;}。然后规约到最上层的语法中然后继续扫描。
然后系统扫描到终结符[FUNCTION],该终结符没有对应的操作。
然后,系统继续扫描,这时候发现了func_name为非终结符。然后跳到func_name所对应的语法结构体中。然后,发现func_name有两个语法[type_function_name]和[Coid Inderction]。扫描流程类似于[opt_or_replace]流程。最终系统会返回一个func_name的链表。


大概流程图:

最终系统匹配了整个语法,然后进入该语法对应的{}中,该{}中定义了一个CreateFunctionStmt的结构体指针,然后分别用对应的$n的值为结构体赋值。

例如:
n->replace = $2。
如果[opt_or_replace]匹配上了[OR REPLACE]语法时,opt_or_replace就会被赋值为true,此时n->replace = $2,该$2表示的就是opt_or_replace的值,此时n->replace就为true。
如果匹配了空,也就是没有对应的标识符。此时n->replace就取的是false。
当系统匹配完整条语法时,就会返回一个CreateFunctionStmt结构体。该结构体中包含了创建函数所需要的所有信息。然后,该结构体就最为ProcessUtility执行器的一个节点传入,然后,根据传入的信息。在系统表中插入相关信息。(创建过程,下个章节介绍),然后函数就创建完毕。




