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