📄 gram.y
字号:
;decl_cursor_arg : decl_varname decl_datatype { PLpgSQL_var *new; new = malloc(sizeof(PLpgSQL_var)); memset(new, 0, sizeof(PLpgSQL_var)); new->dtype = PLPGSQL_DTYPE_VAR; new->refname = $1.name; new->lineno = $1.lineno; new->datatype = $2; new->isconst = false; new->notnull = false; plpgsql_adddatum((PLpgSQL_datum *)new); plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, new->varno, $1.name); $$ = new; } ;decl_is_from : K_IS | /* Oracle */ K_FOR; /* ANSI */decl_aliasitem : T_WORD { char *name; PLpgSQL_nsitem *nsi; plpgsql_convert_ident(yytext, &name, 1); if (name[0] != '$') yyerror("only positional parameters may be aliased"); plpgsql_ns_setlocal(false); nsi = plpgsql_ns_lookup(name, NULL); if (nsi == NULL) { plpgsql_error_lineno = plpgsql_scanner_lineno(); ereport(ERROR, (errcode(ERRCODE_UNDEFINED_PARAMETER), errmsg("function has no parameter \"%s\"", name))); } plpgsql_ns_setlocal(true); pfree(name); $$ = nsi; } ;decl_rowtype : T_ROW { $$ = yylval.row; } ;decl_varname : T_WORD { char *name; plpgsql_convert_ident(yytext, &name, 1); /* name should be malloc'd for use as varname */ $$.name = strdup(name); $$.lineno = plpgsql_scanner_lineno(); pfree(name); } ;decl_renname : T_WORD { char *name; plpgsql_convert_ident(yytext, &name, 1); /* the result must be palloc'd, see plpgsql_ns_rename */ $$ = name; } ;decl_const : { $$ = 0; } | K_CONSTANT { $$ = 1; } ;decl_datatype : { /* * If there's a lookahead token, read_datatype * should consume it. */ $$ = read_datatype(yychar); yyclearin; } ;decl_notnull : { $$ = 0; } | K_NOT K_NULL { $$ = 1; } ;decl_defval : ';' { $$ = NULL; } | decl_defkey { int tok; int lno; PLpgSQL_dstring ds; PLpgSQL_expr *expr; lno = plpgsql_scanner_lineno(); expr = malloc(sizeof(PLpgSQL_expr)); plpgsql_dstring_init(&ds); plpgsql_dstring_append(&ds, "SELECT "); expr->dtype = PLPGSQL_DTYPE_EXPR; expr->plan = NULL; expr->nparams = 0; tok = yylex(); switch (tok) { case 0: yyerror("unexpected end of function"); case K_NULL: if (yylex() != ';') yyerror("expected \";\" after \"NULL\""); free(expr); plpgsql_dstring_free(&ds); $$ = NULL; break; default: plpgsql_dstring_append(&ds, yytext); while ((tok = yylex()) != ';') { if (tok == 0) yyerror("unterminated default value"); if (plpgsql_SpaceScanned) plpgsql_dstring_append(&ds, " "); plpgsql_dstring_append(&ds, yytext); } expr->query = strdup(plpgsql_dstring_get(&ds)); plpgsql_dstring_free(&ds); $$ = expr; break; } } ;decl_defkey : K_ASSIGN | K_DEFAULT ;proc_sect : { PLpgSQL_stmts *new; new = malloc(sizeof(PLpgSQL_stmts)); memset(new, 0, sizeof(PLpgSQL_stmts)); $$ = new; } | proc_stmts { $$ = $1; } ;proc_stmts : proc_stmts proc_stmt { if ($1->stmts_used == $1->stmts_alloc) { $1->stmts_alloc *= 2; $1->stmts = realloc($1->stmts, sizeof(PLpgSQL_stmt *) * $1->stmts_alloc); } $1->stmts[$1->stmts_used++] = (struct PLpgSQL_stmt *)$2; $$ = $1; } | proc_stmt { PLpgSQL_stmts *new; new = malloc(sizeof(PLpgSQL_stmts)); memset(new, 0, sizeof(PLpgSQL_stmts)); new->stmts_alloc = 64; new->stmts_used = 1; new->stmts = malloc(sizeof(PLpgSQL_stmt *) * new->stmts_alloc); new->stmts[0] = (struct PLpgSQL_stmt *)$1; $$ = new; } ;proc_stmt : pl_block ';' { $$ = $1; } | stmt_assign { $$ = $1; } | stmt_if { $$ = $1; } | stmt_loop { $$ = $1; } | stmt_while { $$ = $1; } | stmt_fori { $$ = $1; } | stmt_fors { $$ = $1; } | stmt_select { $$ = $1; } | stmt_exit { $$ = $1; } | stmt_return { $$ = $1; } | stmt_return_next { $$ = $1; } | stmt_raise { $$ = $1; } | stmt_execsql { $$ = $1; } | stmt_dynexecute { $$ = $1; } | stmt_dynfors { $$ = $1; } | stmt_perform { $$ = $1; } | stmt_getdiag { $$ = $1; } | stmt_open { $$ = $1; } | stmt_fetch { $$ = $1; } | stmt_close { $$ = $1; } ;stmt_perform : K_PERFORM lno expr_until_semi { PLpgSQL_stmt_perform *new; new = malloc(sizeof(PLpgSQL_stmt_perform)); memset(new, 0, sizeof(PLpgSQL_stmt_perform)); new->cmd_type = PLPGSQL_STMT_PERFORM; new->lineno = $2; new->expr = $3; $$ = (PLpgSQL_stmt *)new; } ;stmt_assign : assign_var lno K_ASSIGN expr_until_semi { PLpgSQL_stmt_assign *new; new = malloc(sizeof(PLpgSQL_stmt_assign)); memset(new, 0, sizeof(PLpgSQL_stmt_assign)); new->cmd_type = PLPGSQL_STMT_ASSIGN; new->lineno = $2; new->varno = $1; new->expr = $4; $$ = (PLpgSQL_stmt *)new; } ;stmt_getdiag : K_GET K_DIAGNOSTICS lno getdiag_list ';' { PLpgSQL_stmt_getdiag *new; new = malloc(sizeof(PLpgSQL_stmt_getdiag)); memset(new, 0, sizeof(PLpgSQL_stmt_getdiag)); new->cmd_type = PLPGSQL_STMT_GETDIAG; new->lineno = $3; new->ndtitems = $4.nused; new->dtitems = malloc(sizeof(PLpgSQL_diag_item) * $4.nused); memcpy(new->dtitems, $4.dtitems, sizeof(PLpgSQL_diag_item) * $4.nused); $$ = (PLpgSQL_stmt *)new; } ;getdiag_list : getdiag_list ',' getdiag_target K_ASSIGN getdiag_item { if ($1.nused == $1.nalloc) { $1.nalloc *= 2; $1.dtitems = repalloc($1.dtitems, sizeof(PLpgSQL_diag_item) * $1.nalloc); } $1.dtitems[$1.nused].target = $3; $1.dtitems[$1.nused].item = $5; $1.nused++; $$.nalloc = $1.nalloc; $$.nused = $1.nused; $$.dtitems = $1.dtitems; } | getdiag_target K_ASSIGN getdiag_item { $$.nalloc = 1; $$.nused = 1; $$.dtitems = palloc(sizeof(PLpgSQL_diag_item) * $$.nalloc); $$.dtitems[0].target = $1; $$.dtitems[0].item = $3; } ;getdiag_item : K_ROW_COUNT { $$ = PLPGSQL_GETDIAG_ROW_COUNT; } | K_RESULT_OID { $$ = PLPGSQL_GETDIAG_RESULT_OID; } ;getdiag_target : T_VARIABLE { check_assignable(yylval.variable); $$ = yylval.variable->dno; } ;assign_var : T_VARIABLE { check_assignable(yylval.variable); $$ = yylval.variable->dno; } | assign_var '[' expr_until_rightbracket { PLpgSQL_arrayelem *new; new = malloc(sizeof(PLpgSQL_arrayelem)); memset(new, 0, sizeof(PLpgSQL_arrayelem)); new->dtype = PLPGSQL_DTYPE_ARRAYELEM; new->subscript = $3; new->arrayparentno = $1; plpgsql_adddatum((PLpgSQL_datum *)new); $$ = new->dno; } ;stmt_if : K_IF lno expr_until_then proc_sect stmt_else K_END K_IF ';' { PLpgSQL_stmt_if *new; new = malloc(sizeof(PLpgSQL_stmt_if)); memset(new, 0, sizeof(PLpgSQL_stmt_if)); new->cmd_type = PLPGSQL_STMT_IF; new->lineno = $2; new->cond = $3; new->true_body = $4; new->false_body = $5; $$ = (PLpgSQL_stmt *)new; } ;stmt_else : { PLpgSQL_stmts *new; new = malloc(sizeof(PLpgSQL_stmts)); memset(new, 0, sizeof(PLpgSQL_stmts)); $$ = new; } | K_ELSIF lno expr_until_then proc_sect stmt_else { /* * Translate the structure: into: * * IF c1 THEN IF c1 THEN * ... ... * ELSIF c2 THEN ELSE * IF c2 THEN * ... ... * ELSE ELSE * ... ... * END IF END IF * END IF * */ PLpgSQL_stmts *new; PLpgSQL_stmt_if *new_if; /* first create a new if-statement */ new_if = malloc(sizeof(PLpgSQL_stmt_if)); memset(new_if, 0, sizeof(PLpgSQL_stmt_if)); new_if->cmd_type = PLPGSQL_STMT_IF; new_if->lineno = $2; new_if->cond = $3; new_if->true_body = $4; new_if->false_body = $5; /* this is a 'container' for the if-statement */ new = malloc(sizeof(PLpgSQL_stmts)); memset(new, 0, sizeof(PLpgSQL_stmts)); new->stmts_alloc = 64; new->stmts_used = 1; new->stmts = malloc(sizeof(PLpgSQL_stmt *) * new->stmts_alloc); new->stmts[0] = (struct PLpgSQL_stmt *)new_if; $$ = new; } | K_ELSE proc_sect { $$ = $2; } ;stmt_loop : opt_label K_LOOP lno loop_body { PLpgSQL_stmt_loop *new; new = malloc(sizeof(PLpgSQL_stmt_loop)); memset(new, 0, sizeof(PLpgSQL_stmt_loop)); new->cmd_type = PLPGSQL_STMT_LOOP; new->lineno = $3; new->label = $1; new->body = $4; plpgsql_ns_pop(); $$ = (PLpgSQL_stmt *)new; } ;stmt_while : opt_label K_WHILE lno expr_until_loop loop_body { PLpgSQL_stmt_while *new; new = malloc(sizeof(PLpgSQL_stmt_while)); memset(new, 0, sizeof(PLpgSQL_stmt_while)); new->cmd_type = PLPGSQL_STMT_WHILE; new->lineno = $3; new->label = $1; new->cond = $4; new->body = $5; plpgsql_ns_pop(); $$ = (PLpgSQL_stmt *)new; } ;stmt_fori : opt_label K_FOR lno fori_var K_IN fori_lower expr_until_loop loop_body { PLpgSQL_stmt_fori *new; new = malloc(sizeof(PLpgSQL_stmt_fori)); memset(new, 0, sizeof(PLpgSQL_stmt_fori)); new->cmd_type = PLPGSQL_STMT_FORI; new->lineno = $3; new->label = $1; new->var = $4; new->reverse = $6.reverse; new->lower = $6.expr; new->upper = $7; new->body = $8; plpgsql_ns_pop(); $$ = (PLpgSQL_stmt *)new; } ;fori_var : fori_varname { PLpgSQL_var *new; new = malloc(sizeof(PLpgSQL_var)); memset(new, 0, sizeof(PLpgSQL_var)); new->dtype = PLPGSQL_DTYPE_VAR; new->refname = $1.name; new->lineno = $1.lineno; new->datatype = plpgsql_parse_datatype("integer"); new->isconst = false; new->notnull = false; new->default_val = NULL; plpgsql_adddatum((PLpgSQL_datum *)new); plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, new->varno, $1.name); plpgsql_add_initdatums(NULL); $$ = new; } ;fori_varname : T_VARIABLE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -