Commit | Line | Data |
---|---|---|
c0bc4ef7 | 1 | /* |
30f48914 KB |
2 | * Copyright (c) 1985 Sun Microsystems, Inc. |
3 | * Copyright (c) 1980 The Regents of the University of California. | |
b0627149 KB |
4 | * Copyright (c) 1976 Board of Trustees of the University of Illinois. |
5 | * All rights reserved. | |
6 | * | |
7 | * Redistribution and use in source and binary forms are permitted | |
b36fc510 KB |
8 | * provided that the above copyright notice and this paragraph are |
9 | * duplicated in all such forms and that any documentation, | |
10 | * advertising materials, and other materials related to such | |
11 | * distribution and use acknowledge that the software was developed | |
30f48914 KB |
12 | * by the University of California, Berkeley, the University of Illinois, |
13 | * Urbana, and Sun Microsystems, Inc. The name of either University | |
14 | * or Sun Microsystems may not be used to endorse or promote products | |
15 | * derived from this software without specific prior written permission. | |
b36fc510 KB |
16 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR |
17 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
18 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
c0bc4ef7 DF |
19 | */ |
20 | ||
21 | #ifndef lint | |
b7f39038 | 22 | static char sccsid[] = "@(#)parse.c 5.8 (Berkeley) %G%"; |
b0627149 | 23 | #endif /* not lint */ |
d57be9f7 | 24 | |
b7f39038 KB |
25 | #include "./indent_globs.h" |
26 | #include "./indent_codes.h" | |
d57be9f7 KM |
27 | |
28 | ||
d57be9f7 KM |
29 | |
30 | ||
1009bf5e KM |
31 | parse(tk) |
32 | int tk; /* the code for the construct scanned */ | |
d57be9f7 | 33 | { |
1009bf5e | 34 | int i; |
d57be9f7 KM |
35 | |
36 | #ifdef debug | |
1009bf5e | 37 | printf("%2d - %s\n", tk, token); |
d57be9f7 | 38 | #endif |
30f48914 | 39 | |
1009bf5e KM |
40 | while (ps.p_stack[ps.tos] == ifhead && tk != elselit) { |
41 | /* true if we have an if without an else */ | |
42 | ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::= stmt | |
30f48914 | 43 | * reduction */ |
1009bf5e | 44 | reduce(); /* see if this allows any reduction */ |
d57be9f7 KM |
45 | } |
46 | ||
47 | ||
30f48914 KB |
48 | switch (tk) { /* go on and figure out what to do with the |
49 | * input */ | |
1009bf5e | 50 | |
30f48914 KB |
51 | case decl: /* scanned a declaration word */ |
52 | ps.search_brace = btype_2; | |
53 | /* indicate that following brace should be on same line */ | |
54 | if (ps.p_stack[ps.tos] != decl) { /* only put one declaration | |
55 | * onto stack */ | |
56 | break_comma = true; /* while in declaration, newline should be | |
57 | * forced after comma */ | |
58 | ps.p_stack[++ps.tos] = decl; | |
1009bf5e | 59 | ps.il[ps.tos] = ps.i_l_follow; |
d57be9f7 | 60 | |
30f48914 KB |
61 | if (ps.ljust_decl) {/* only do if we want left justified |
62 | * declarations */ | |
63 | ps.ind_level = 0; | |
64 | for (i = ps.tos - 1; i > 0; --i) | |
65 | if (ps.p_stack[i] == decl) | |
66 | ++ps.ind_level; /* indentation is number of | |
67 | * declaration levels deep we are */ | |
68 | ps.i_l_follow = ps.ind_level; | |
d57be9f7 | 69 | } |
30f48914 KB |
70 | } |
71 | break; | |
72 | ||
73 | case ifstmt: /* scanned if (...) */ | |
74 | if (ps.p_stack[ps.tos] == elsehead && ps.else_if) /* "else if ..." */ | |
75 | ps.i_l_follow = ps.il[ps.tos]; | |
76 | case dolit: /* 'do' */ | |
77 | case forstmt: /* for (...) */ | |
78 | ps.p_stack[++ps.tos] = tk; | |
79 | ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; | |
80 | ++ps.i_l_follow; /* subsequent statements should be indented 1 */ | |
81 | ps.search_brace = btype_2; | |
82 | break; | |
83 | ||
84 | case lbrace: /* scanned { */ | |
85 | break_comma = false; /* don't break comma in an initial list */ | |
86 | if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl | |
87 | || ps.p_stack[ps.tos] == stmtl) | |
88 | ++ps.i_l_follow; /* it is a random, isolated stmt group or a | |
89 | * declaration */ | |
90 | else { | |
91 | if (s_code == e_code) { | |
92 | /* | |
93 | * only do this if there is nothing on the line | |
94 | */ | |
95 | --ps.ind_level; | |
96 | /* | |
97 | * it is a group as part of a while, for, etc. | |
98 | */ | |
99 | if (ps.p_stack[ps.tos] == swstmt && ps.case_indent >= 1) | |
100 | --ps.ind_level; | |
101 | /* | |
102 | * for a switch, brace should be two levels out from the code | |
103 | */ | |
d57be9f7 | 104 | } |
30f48914 | 105 | } |
d57be9f7 | 106 | |
30f48914 KB |
107 | ps.p_stack[++ps.tos] = lbrace; |
108 | ps.il[ps.tos] = ps.ind_level; | |
109 | ps.p_stack[++ps.tos] = stmt; | |
110 | /* allow null stmt between braces */ | |
111 | ps.il[ps.tos] = ps.i_l_follow; | |
112 | break; | |
113 | ||
114 | case whilestmt: /* scanned while (...) */ | |
115 | if (ps.p_stack[ps.tos] == dohead) { | |
116 | /* it is matched with do stmt */ | |
117 | ps.ind_level = ps.i_l_follow = ps.il[ps.tos]; | |
118 | ps.p_stack[++ps.tos] = whilestmt; | |
119 | ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; | |
120 | } | |
121 | else { /* it is a while loop */ | |
122 | ps.p_stack[++ps.tos] = whilestmt; | |
123 | ps.il[ps.tos] = ps.i_l_follow; | |
124 | ++ps.i_l_follow; | |
125 | ps.search_brace = btype_2; | |
126 | } | |
d57be9f7 | 127 | |
30f48914 | 128 | break; |
d57be9f7 | 129 | |
30f48914 | 130 | case elselit: /* scanned an else */ |
d57be9f7 | 131 | |
30f48914 KB |
132 | if (ps.p_stack[ps.tos] != ifhead) |
133 | diag(1, "Unmatched 'else'"); | |
134 | else { | |
135 | ps.ind_level = ps.il[ps.tos]; /* indentation for else should | |
136 | * be same as for if */ | |
137 | ps.i_l_follow = ps.ind_level + 1; /* everything following should | |
138 | * be in 1 level */ | |
139 | ps.p_stack[ps.tos] = elsehead; | |
140 | /* remember if with else */ | |
141 | ps.search_brace = btype_2 | ps.else_if; | |
142 | } | |
143 | break; | |
d57be9f7 | 144 | |
30f48914 KB |
145 | case rbrace: /* scanned a } */ |
146 | /* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */ | |
147 | if (ps.p_stack[ps.tos - 1] == lbrace) { | |
148 | ps.ind_level = ps.i_l_follow = ps.il[--ps.tos]; | |
149 | ps.p_stack[ps.tos] = stmt; | |
150 | } | |
151 | else | |
152 | diag(1, "Stmt nesting error."); | |
153 | break; | |
154 | ||
155 | case swstmt: /* had switch (...) */ | |
156 | ps.p_stack[++ps.tos] = swstmt; | |
157 | ps.cstk[ps.tos] = case_ind; | |
158 | /* save current case indent level */ | |
159 | ps.il[ps.tos] = ps.i_l_follow; | |
160 | case_ind = ps.i_l_follow + ps.case_indent; /* cases should be one | |
1009bf5e KM |
161 | * level down from |
162 | * switch */ | |
b7f39038 | 163 | ps.i_l_follow += ps.case_indent + 1; /* statements should be two |
30f48914 KB |
164 | * levels in */ |
165 | ps.search_brace = btype_2; | |
166 | break; | |
d57be9f7 | 167 | |
30f48914 KB |
168 | case semicolon: /* this indicates a simple stmt */ |
169 | break_comma = false; /* turn off flag to break after commas in a | |
170 | * declaration */ | |
171 | ps.p_stack[++ps.tos] = stmt; | |
172 | ps.il[ps.tos] = ps.ind_level; | |
173 | break; | |
d57be9f7 | 174 | |
30f48914 KB |
175 | default: /* this is an error */ |
176 | diag(1, "Unknown code to parser"); | |
177 | return; | |
d57be9f7 KM |
178 | |
179 | ||
1009bf5e | 180 | } /* end of switch */ |
d57be9f7 | 181 | |
1009bf5e | 182 | reduce(); /* see if any reduction can be done */ |
30f48914 | 183 | |
d57be9f7 | 184 | #ifdef debug |
1009bf5e KM |
185 | for (i = 1; i <= ps.tos; ++i) |
186 | printf("(%d %d)", ps.p_stack[i], ps.il[i]); | |
187 | printf("\n"); | |
d57be9f7 | 188 | #endif |
30f48914 | 189 | |
d57be9f7 KM |
190 | return; |
191 | } | |
30f48914 KB |
192 | |
193 | /* | |
194 | * Copyright (C) 1976 by the Board of Trustees of the University of Illinois | |
195 | * | |
196 | * All rights reserved | |
197 | * | |
198 | * | |
199 | * NAME: reduce | |
200 | * | |
201 | * FUNCTION: Implements the reduce part of the parsing algorithm | |
202 | * | |
203 | * ALGORITHM: The following reductions are done. Reductions are repeated until | |
204 | * no more are possible. | |
205 | * | |
1009bf5e | 206 | * Old TOS New TOS <stmt> <stmt> <stmtl> <stmtl> <stmt> <stmtl> do |
30f48914 KB |
207 | * <stmt> "dostmt" if <stmt> "ifstmt" switch <stmt> <stmt> decl |
208 | * <stmt> <stmt> "ifelse" <stmt> <stmt> for <stmt> <stmt> while | |
209 | * <stmt> <stmt> "dostmt" while <stmt> | |
210 | * | |
1009bf5e | 211 | * On each reduction, ps.i_l_follow (the indentation for the following line) is |
30f48914 KB |
212 | * set to the indentation level associated with the old TOS. |
213 | * | |
214 | * PARAMETERS: None | |
215 | * | |
216 | * RETURNS: Nothing | |
217 | * | |
218 | * GLOBALS: ps.cstk ps.i_l_follow = ps.il ps.p_stack = ps.tos = | |
219 | * | |
220 | * CALLS: None | |
221 | * | |
1009bf5e | 222 | * CALLED BY: parse \1c |
30f48914 KB |
223 | * |
224 | * HISTORY: initial coding November 1976 D A Willcox of CAC | |
225 | * | |
1009bf5e | 226 | */\f |
d57be9f7 | 227 | /*----------------------------------------------*\ |
30f48914 | 228 | | REDUCTION PHASE | |
d57be9f7 | 229 | \*----------------------------------------------*/ |
30f48914 KB |
230 | reduce() |
231 | { | |
d57be9f7 | 232 | |
1009bf5e | 233 | register int i; |
d57be9f7 | 234 | |
30f48914 KB |
235 | for (;;) { /* keep looping until there is nothing left to |
236 | * reduce */ | |
d57be9f7 | 237 | |
1009bf5e | 238 | switch (ps.p_stack[ps.tos]) { |
d57be9f7 | 239 | |
30f48914 KB |
240 | case stmt: |
241 | switch (ps.p_stack[ps.tos - 1]) { | |
242 | ||
243 | case stmt: | |
244 | case stmtl: | |
245 | /* stmtl stmt or stmt stmt */ | |
246 | ps.p_stack[--ps.tos] = stmtl; | |
d57be9f7 KM |
247 | break; |
248 | ||
30f48914 KB |
249 | case dolit: /* <do> <stmt> */ |
250 | ps.p_stack[--ps.tos] = dohead; | |
251 | ps.i_l_follow = ps.il[ps.tos]; | |
252 | break; | |
253 | ||
254 | case ifstmt: | |
255 | /* <if> <stmt> */ | |
256 | ps.p_stack[--ps.tos] = ifhead; | |
257 | for (i = ps.tos - 1; | |
258 | ( | |
259 | ps.p_stack[i] != stmt | |
260 | && | |
261 | ps.p_stack[i] != stmtl | |
262 | && | |
263 | ps.p_stack[i] != lbrace | |
264 | ); | |
265 | --i); | |
266 | ps.i_l_follow = ps.il[i]; | |
267 | /* | |
268 | * for the time being, we will assume that there is no else on | |
269 | * this if, and set the indentation level accordingly. If an | |
270 | * else is scanned, it will be fixed up later | |
271 | */ | |
272 | break; | |
d57be9f7 | 273 | |
30f48914 KB |
274 | case swstmt: |
275 | /* <switch> <stmt> */ | |
276 | case_ind = ps.cstk[ps.tos - 1]; | |
277 | ||
278 | case decl: /* finish of a declaration */ | |
279 | case elsehead: | |
280 | /* <<if> <stmt> else> <stmt> */ | |
281 | case forstmt: | |
282 | /* <for> <stmt> */ | |
283 | case whilestmt: | |
284 | /* <while> <stmt> */ | |
285 | ps.p_stack[--ps.tos] = stmt; | |
286 | ps.i_l_follow = ps.il[ps.tos]; | |
287 | break; | |
288 | ||
289 | default: /* <anything else> <stmt> */ | |
290 | return; | |
291 | ||
292 | } /* end of section for <stmt> on top of stack */ | |
293 | break; | |
294 | ||
295 | case whilestmt: /* while (...) on top */ | |
296 | if (ps.p_stack[ps.tos - 1] == dohead) { | |
297 | /* it is termination of a do while */ | |
298 | ps.p_stack[--ps.tos] = stmt; | |
299 | break; | |
300 | } | |
301 | else | |
d57be9f7 KM |
302 | return; |
303 | ||
30f48914 KB |
304 | default: /* anything else on top */ |
305 | return; | |
306 | ||
1009bf5e KM |
307 | } |
308 | } | |
d57be9f7 | 309 | } |