PostgreSQL Source Code git master
Loading...
Searching...
No Matches
parse.c File Reference
#include "c.h"
#include <err.h>
#include <stdio.h>
#include "indent_globs.h"
#include "indent_codes.h"
#include "indent.h"
Include dependency graph for parse.c:

Go to the source code of this file.

Functions

static void reduce (void)
 
void parse (int tk)
 

Function Documentation

◆ parse()

void parse ( int  tk)

Definition at line 49 of file parse.c.

50{
51 int i;
52
53#ifdef debug
54 printf("%2d - %s\n", tk, token);
55#endif
56
57 while (ps.p_stack[ps.tos] == ifhead && tk != elselit) {
58 /* true if we have an if without an else */
59 ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::= stmt
60 * reduction */
61 reduce(); /* see if this allows any reduction */
62 }
63
64
65 switch (tk) { /* go on and figure out what to do with the
66 * input */
67
68 case decl: /* scanned a declaration word */
70 /* indicate that following brace should be on same line */
71 if (ps.p_stack[ps.tos] != decl) { /* only put one declaration
72 * onto stack */
73 break_comma = true; /* while in declaration, newline should be
74 * forced after comma */
75 ps.p_stack[++ps.tos] = decl;
77
78 if (ps.ljust_decl) {/* only do if we want left justified
79 * declarations */
80 ps.ind_level = 0;
81 for (i = ps.tos - 1; i > 0; --i)
82 if (ps.p_stack[i] == decl)
83 ++ps.ind_level; /* indentation is number of
84 * declaration levels deep we are */
86 }
87 }
88 break;
89
90 case ifstmt: /* scanned if (...) */
91 if (ps.p_stack[ps.tos] == elsehead && ps.else_if) /* "else if ..." */
92 /*
93 * Note that the stack pointer here is decremented, effectively
94 * reducing "else if" to "if". This saves a lot of stack space
95 * in case of a long "if-else-if ... else-if" sequence.
96 */
97 ps.i_l_follow = ps.il[ps.tos--];
98 /* the rest is the same as for dolit and forstmt */
99 /* FALLTHROUGH */
100 case dolit: /* 'do' */
101 case forstmt: /* for (...) */
102 ps.p_stack[++ps.tos] = tk;
104 ++ps.i_l_follow; /* subsequent statements should be indented 1 */
106 break;
107
108 case lbrace: /* scanned { */
109 break_comma = false; /* don't break comma in an initial list */
110 if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl
111 || ps.p_stack[ps.tos] == stmtl)
112 ++ps.i_l_follow; /* it is a random, isolated stmt group or a
113 * declaration */
114 else {
115 if (s_code == e_code) {
116 /*
117 * only do this if there is nothing on the line
118 */
119 --ps.ind_level;
120 /*
121 * it is a group as part of a while, for, etc.
122 */
123 if (ps.p_stack[ps.tos] == swstmt && ps.case_indent >= 1)
124 --ps.ind_level;
125 /*
126 * for a switch, brace should be two levels out from the code
127 */
128 }
129 }
130
131 ps.p_stack[++ps.tos] = lbrace;
132 ps.il[ps.tos] = ps.ind_level;
133 ps.p_stack[++ps.tos] = stmt;
134 /* allow null stmt between braces */
135 ps.il[ps.tos] = ps.i_l_follow;
136 break;
137
138 case whilestmt: /* scanned while (...) */
139 if (ps.p_stack[ps.tos] == dohead) {
140 /* it is matched with do stmt */
144 }
145 else { /* it is a while loop */
147 ps.il[ps.tos] = ps.i_l_follow;
148 ++ps.i_l_follow;
150 }
151
152 break;
153
154 case elselit: /* scanned an else */
155
156 if (ps.p_stack[ps.tos] != ifhead)
157 diag2(1, "Unmatched 'else'");
158 else {
159 ps.ind_level = ps.il[ps.tos]; /* indentation for else should
160 * be same as for if */
161 ps.i_l_follow = ps.ind_level + 1; /* everything following should
162 * be in 1 level */
164 /* remember if with else */
166 }
167 break;
168
169 case rbrace: /* scanned a } */
170 /* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */
171 if (ps.tos > 0 && ps.p_stack[ps.tos - 1] == lbrace) {
173 ps.p_stack[ps.tos] = stmt;
174 }
175 else
176 diag2(1, "Statement nesting error");
177 break;
178
179 case swstmt: /* had switch (...) */
180 ps.p_stack[++ps.tos] = swstmt;
181 ps.cstk[ps.tos] = case_ind;
182 /* save current case indent level */
183 ps.il[ps.tos] = ps.i_l_follow;
184 case_ind = ps.i_l_follow + ps.case_indent; /* cases should be one
185 * level down from
186 * switch */
187 ps.i_l_follow += ps.case_indent + 1; /* statements should be two
188 * levels in */
190 break;
191
192 case semicolon: /* this indicates a simple stmt */
193 break_comma = false; /* turn off flag to break after commas in a
194 * declaration */
195 ps.p_stack[++ps.tos] = stmt;
196 ps.il[ps.tos] = ps.ind_level;
197 break;
198
199 default: /* this is an error */
200 diag2(1, "Unknown code to parser");
201 return;
202
203
204 } /* end of switch */
205
206 if (ps.tos >= nitems(ps.p_stack) - 1)
207 errx(1, "Parser stack overflow");
208
209 reduce(); /* see if any reduction can be done */
210
211#ifdef debug
212 for (i = 1; i <= ps.tos; ++i)
213 printf("(%d %d)", ps.p_stack[i], ps.il[i]);
214 printf("\n");
215#endif
216
217 return;
218}
void errx(int eval, const char *fmt,...)
Definition err.c:58
void diag2(int, const char *)
Definition io.c:590
#define nitems(x)
Definition indent.h:31
#define stmt
#define whilestmt
#define swstmt
#define ifhead
#define rbrace
#define ifstmt
#define lbrace
#define semicolon
#define forstmt
#define dolit
#define dohead
#define elsehead
#define elselit
#define stmtl
#define decl
int btype_2
char * e_code
struct parser_state ps
int break_comma
float case_ind
char * s_code
int i
Definition isn.c:77
static void reduce(void)
Definition parse.c:260
#define printf(...)
Definition port.h:266
static int fb(int x)
float cstk[32]
int p_stack[256]

References break_comma, btype_2, case_ind, parser_state::case_indent, parser_state::cstk, decl, diag2(), dohead, dolit, e_code, parser_state::else_if, elsehead, elselit, errx(), fb(), forstmt, i, parser_state::i_l_follow, ifhead, ifstmt, parser_state::il, parser_state::ind_level, lbrace, parser_state::ljust_decl, nitems, parser_state::p_stack, parse(), printf, ps, rbrace, reduce(), s_code, parser_state::search_brace, semicolon, stmt, stmtl, swstmt, parser_state::tos, and whilestmt.

Referenced by add_foreign_final_paths(), add_foreign_grouping_paths(), add_foreign_ordered_paths(), add_paths_to_grouping_rel(), build_minmax_path(), build_mvdependencies(), build_mvndistinct(), can_partial_agg(), check_sql_stmt_retval(), consider_groupingsets_paths(), convert_ANY_sublink_to_join(), convert_EXISTS_sublink_to_join(), create_degenerate_grouping_paths(), create_final_distinct_paths(), create_grouping_paths(), create_limit_plan(), create_partial_distinct_paths(), create_partial_grouping_paths(), delay_execution_planner(), dependencies_array_element_start(), dependencies_array_end(), dependencies_array_start(), dependencies_object_end(), dependencies_object_field_start(), dependencies_object_start(), dependencies_scalar(), distribute_row_identity_vars(), expand_single_inheritance_child(), expand_virtual_generated_columns(), flatten_simple_union_all(), get_nullingrels(), get_number_of_groups(), get_sql_fn_result_tlist(), get_useful_group_keys_orderings(), grouping_planner(), is_degenerate_grouping(), json_manifest_array_end(), json_manifest_array_start(), json_manifest_finalize_file(), json_manifest_finalize_system_identifier(), json_manifest_finalize_version(), json_manifest_finalize_wal_range(), json_manifest_object_end(), json_manifest_object_field_start(), json_manifest_object_start(), json_manifest_scalar(), json_parse_manifest(), json_parse_manifest_incremental_chunk(), json_parse_manifest_incremental_init(), limit_needed(), main(), make_group_input_target(), make_sort_input_target(), max_parallel_hazard(), ndistinct_array_element_start(), ndistinct_array_end(), ndistinct_array_start(), ndistinct_object_end(), ndistinct_object_field_start(), ndistinct_object_start(), ndistinct_scalar(), parse(), perform_pullup_replace_vars(), pgss_planner(), plan_set_operations(), planner(), preprocess_groupclause(), preprocess_grouping_sets(), preprocess_limit(), preprocess_minmax_aggregates(), preprocess_relation_rtes(), preprocess_rowmarks(), preprocess_targetlist(), pull_up_constant_function(), pull_up_simple_subquery(), pull_up_simple_values(), query_planner(), remove_useless_groupby_columns(), replace_empty_jointree(), resolve_unique_index_expr(), set_subquery_pathlist(), standard_planner(), standard_qp_callback(), subquery_planner(), transform_MERGE_to_join(), and verify_manifest_checksum().

◆ reduce()

static void reduce ( void  )
static

Definition at line 260 of file parse.c.

261{
262 int i;
263
264 for (;;) { /* keep looping until there is nothing left to
265 * reduce */
266
267 switch (ps.p_stack[ps.tos]) {
268
269 case stmt:
270 switch (ps.p_stack[ps.tos - 1]) {
271
272 case stmt:
273 case stmtl:
274 /* stmtl stmt or stmt stmt */
275 ps.p_stack[--ps.tos] = stmtl;
276 break;
277
278 case dolit: /* <do> <stmt> */
279 ps.p_stack[--ps.tos] = dohead;
280 ps.i_l_follow = ps.il[ps.tos];
281 break;
282
283 case ifstmt:
284 /* <if> <stmt> */
285 ps.p_stack[--ps.tos] = ifhead;
286 for (i = ps.tos - 1;
287 (
288 ps.p_stack[i] != stmt
289 &&
290 ps.p_stack[i] != stmtl
291 &&
292 ps.p_stack[i] != lbrace
293 );
294 --i);
295 ps.i_l_follow = ps.il[i];
296 /*
297 * for the time being, we will assume that there is no else on
298 * this if, and set the indentation level accordingly. If an
299 * else is scanned, it will be fixed up later
300 */
301 break;
302
303 case swstmt:
304 /* <switch> <stmt> */
305 case_ind = ps.cstk[ps.tos - 1];
306 /* FALLTHROUGH */
307 case decl: /* finish of a declaration */
308 case elsehead:
309 /* <<if> <stmt> else> <stmt> */
310 case forstmt:
311 /* <for> <stmt> */
312 case whilestmt:
313 /* <while> <stmt> */
314 ps.p_stack[--ps.tos] = stmt;
315 ps.i_l_follow = ps.il[ps.tos];
316 break;
317
318 default: /* <anything else> <stmt> */
319 return;
320
321 } /* end of section for <stmt> on top of stack */
322 break;
323
324 case whilestmt: /* while (...) on top */
325 if (ps.p_stack[ps.tos - 1] == dohead) {
326 /* it is termination of a do while */
327 ps.tos -= 2;
328 break;
329 }
330 else
331 return;
332
333 default: /* anything else on top */
334 return;
335
336 }
337 }
338}

References case_ind, parser_state::cstk, decl, dohead, dolit, elsehead, forstmt, i, parser_state::i_l_follow, ifhead, ifstmt, parser_state::il, lbrace, parser_state::p_stack, ps, stmt, stmtl, swstmt, parser_state::tos, and whilestmt.

Referenced by parse(), and startScan().