source: trunk/minix/commands/indent/parse.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

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