PostgreSQL Source Code
git master
parse.c
Go to the documentation of this file.
1
/*-
2
* Copyright (c) 1985 Sun Microsystems, Inc.
3
* Copyright (c) 1980, 1993
4
* The Regents of the University of California. All rights reserved.
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
* 3. Neither the name of the University nor the names of its contributors
16
* may be used to endorse or promote products derived from this software
17
* without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
* SUCH DAMAGE.
30
*/
31
32
#if 0
33
#ifndef lint
34
static
char
sccsid[] =
"@(#)parse.c 8.1 (Berkeley) 6/6/93"
;
35
#endif
/* not lint */
36
#endif
37
38
#include "
c.h
"
39
40
#include <
err.h
>
41
#include <stdio.h>
42
#include "
indent_globs.h
"
43
#include "
indent_codes.h
"
44
#include "
indent.h
"
45
46
static
void
reduce
(
void
);
47
48
void
49
parse
(
int
tk)
/* tk: the code for the construct scanned */
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 */
69
ps
.
search_brace
=
btype_2
;
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
;
76
ps
.
il
[
ps
.
tos
] =
ps
.
i_l_follow
;
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 */
85
ps
.
i_l_follow
=
ps
.
ind_level
;
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;
103
ps
.
il
[
ps
.
tos
] =
ps
.
ind_level
=
ps
.
i_l_follow
;
104
++
ps
.
i_l_follow
;
/* subsequent statements should be indented 1 */
105
ps
.
search_brace
=
btype_2
;
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 */
141
ps
.
ind_level
=
ps
.
i_l_follow
=
ps
.
il
[
ps
.
tos
];
142
ps
.
p_stack
[++
ps
.
tos
] =
whilestmt
;
143
ps
.
il
[
ps
.
tos
] =
ps
.
ind_level
=
ps
.
i_l_follow
;
144
}
145
else
{
/* it is a while loop */
146
ps
.
p_stack
[++
ps
.
tos
] =
whilestmt
;
147
ps
.
il
[
ps
.
tos
] =
ps
.
i_l_follow
;
148
++
ps
.
i_l_follow
;
149
ps
.
search_brace
=
btype_2
;
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 */
163
ps
.
p_stack
[
ps
.
tos
] =
elsehead
;
164
/* remember if with else */
165
ps
.
search_brace
=
btype_2
|
ps
.
else_if
;
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
) {
172
ps
.
ind_level
=
ps
.
i_l_follow
=
ps
.
il
[--
ps
.
tos
];
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 */
189
ps
.
search_brace
=
btype_2
;
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
}
219
220
/*
221
* NAME: reduce
222
*
223
* FUNCTION: Implements the reduce part of the parsing algorithm
224
*
225
* ALGORITHM: The following reductions are done. Reductions are repeated
226
* until no more are possible.
227
*
228
* Old TOS New TOS
229
* <stmt> <stmt> <stmtl>
230
* <stmtl> <stmt> <stmtl>
231
* do <stmt> "dostmt"
232
* if <stmt> "ifstmt"
233
* switch <stmt> <stmt>
234
* decl <stmt> <stmt>
235
* "ifelse" <stmt> <stmt>
236
* for <stmt> <stmt>
237
* while <stmt> <stmt>
238
* "dostmt" while <stmt>
239
*
240
* On each reduction, ps.i_l_follow (the indentation for the following line)
241
* is set to the indentation level associated with the old TOS.
242
*
243
* PARAMETERS: None
244
*
245
* RETURNS: Nothing
246
*
247
* GLOBALS: ps.cstk ps.i_l_follow = ps.il ps.p_stack = ps.tos =
248
*
249
* CALLS: None
250
*
251
* CALLED BY: parse
252
*
253
* HISTORY: initial coding November 1976 D A Willcox of CAC
254
*
255
*/
256
/*----------------------------------------------*\
257
| REDUCTION PHASE |
258
\*----------------------------------------------*/
259
static
void
260
reduce
(
void
)
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
}
c.h
errx
void errx(int eval, const char *fmt,...)
Definition:
err.c:58
err.h
indent.h
diag2
void diag2(int, const char *)
Definition:
io.c:590
nitems
#define nitems(x)
Definition:
indent.h:31
indent_codes.h
stmt
#define stmt
Definition:
indent_codes.h:59
whilestmt
#define whilestmt
Definition:
indent_codes.h:57
swstmt
#define swstmt
Definition:
indent_codes.h:50
ifhead
#define ifhead
Definition:
indent_codes.h:64
rbrace
#define rbrace
Definition:
indent_codes.h:46
ifstmt
#define ifstmt
Definition:
indent_codes.h:56
lbrace
#define lbrace
Definition:
indent_codes.h:45
semicolon
#define semicolon
Definition:
indent_codes.h:44
forstmt
#define forstmt
Definition:
indent_codes.h:58
dolit
#define dolit
Definition:
indent_codes.h:62
dohead
#define dohead
Definition:
indent_codes.h:63
elsehead
#define elsehead
Definition:
indent_codes.h:65
elselit
#define elselit
Definition:
indent_codes.h:61
stmtl
#define stmtl
Definition:
indent_codes.h:60
decl
#define decl
Definition:
indent_codes.h:53
indent_globs.h
token
#define token
Definition:
indent_globs.h:126
btype_2
int btype_2
e_code
char * e_code
ps
struct parser_state ps
break_comma
int break_comma
case_ind
float case_ind
s_code
char * s_code
i
int i
Definition:
isn.c:73
reduce
static void reduce(void)
Definition:
parse.c:260
parse
void parse(int tk)
Definition:
parse.c:49
printf
#define printf(...)
Definition:
port.h:244
parser_state::i_l_follow
int i_l_follow
Definition:
indent_globs.h:275
parser_state::tos
int tos
Definition:
indent_globs.h:326
parser_state::search_brace
int search_brace
Definition:
indent_globs.h:304
parser_state::ljust_decl
int ljust_decl
Definition:
indent_globs.h:290
parser_state::cstk
float cstk[32]
Definition:
indent_globs.h:237
parser_state::ind_level
int ind_level
Definition:
indent_globs.h:281
parser_state::else_if
int else_if
Definition:
indent_globs.h:316
parser_state::il
int il[64]
Definition:
indent_globs.h:236
parser_state::case_indent
float case_indent
Definition:
indent_globs.h:322
parser_state::p_stack
int p_stack[256]
Definition:
indent_globs.h:235
src
tools
pg_bsd_indent
parse.c
Generated on Tue Oct 8 2024 00:13:27 for PostgreSQL Source Code by
1.9.1