1: static char sccsid[] = "@(#)parse.c 4.1 (Berkeley) 10/21/82";
2:
3: /*
4:
5: Copyright (C) 1976
6: by the
7: Board of Trustees
8: of the
9: University of Illinois
10:
11: All rights reserved
12:
13:
14: FILE NAME:
15: parse.c
16:
17: PURPOSE:
18: Contains the routines which keep track of the parse stack.
19:
20: GLOBALS:
21: p_stack = The parse stack, set by both routines
22: il = Stack of indentation levels, set by parse
23: cstk = Stack of case statement indentation levels, set by parse
24: tos = Pointer to top of stack, set by both routines.
25:
26: FUNCTIONS:
27: parse
28: reduce
29: */
30: /*
31:
32: Copyright (C) 1976
33: by the
34: Board of Trustees
35: of the
36: University of Illinois
37:
38: All rights reserved
39:
40:
41: NAME:
42: parse
43:
44: FUNCTION:
45: Parse is given one input which is a "maxi token" just scanned from
46: input. Maxi tokens are signifigant constructs such as else, {, do,
47: if (...), etc. Parse works with reduce to maintain a parse stack
48: of these constructs. Parse is responsible for the "shift" portion
49: of the parse algorithm, and reduce handles the "reduce" portion.
50:
51: ALGORITHM:
52: 1) If there is "ifstmt" on the stack and input is anything other than
53: an else, then change the top of stack (TOS) to <stmt>. Do a reduce.
54: 2) Use a switch statement to implement the following shift operations:
55:
56: TOS___ Input_____ Stack_____ Note____
57: decl decl nothing
58: anything else decl decl
59: "dostmt" while (..) Change TOS to <stmt>
60: anything else while (..) while
61: "ifstmt" else Change TOS to "ifelse"
62: { <stmtl> } Change { <stmtl>
63: to <stmtl>
64: switch (..) switch
65: do do
66: for(..) for
67: ; <stmt>
68: { { <stmt>
69:
70: PARAMETERS:
71: tk An integer code for the maxi token scanned
72:
73: RETURNS:
74: Nothing
75:
76: GLOBALS:
77: break_comma = Set to true when in a declaration but not initialization
78: btype_2
79: case_ind =
80: cstk =
81: i_l_follow =
82: il = Stack of indentation levels
83: ind_level =
84: p_stack = Stack of token codes
85: search_brace = Set to true if we must look for possibility of moving a
86: brace
87: tos = Pointer to top of p_stack, il, and cstk
88:
89: CALLS:
90: printf (lib)
91: reduce
92:
93: CALLED BY:
94: main
95:
96: HISTORY:
97: initial coding November 1976 D A Willcox of CAC
98:
99: */
100:
101: #include "./indent_globs.h";
102: #include "./indent_codes.h";
103:
104:
105: int p_stack[50] = stmt;
106: /* this is the parser's stack */
107: int il[50]; /* this stack stores indentation levels */
108: int cstk[50]; /* used to store case stmt indentation levels */
109: int tos = 0; /* pointer to top of stack */
110:
111:
112: parse (tk)
113: int tk; /* the code for the construct scanned */
114: {
115: int i;
116:
117: #ifdef debug
118: printf ("%2d - %s\n", tk, token);
119: #endif
120: while (p_stack[tos] == ifhead && tk != elselit) {
121: /* true if we have an if without an else */
122: p_stack[tos] = stmt; /* apply the if(..) stmt ::= stmt reduction */
123: reduce (); /* see if this allows any reduction */
124: }
125:
126:
127: switch (tk) { /* go on and figure out what to do with the
128: input */
129:
130: case decl: /* scanned a declaration word */
131: search_brace = btype_2;
132: /* indicate that following brace should be on same line */
133: if (p_stack[tos] != decl) {
134: /* only put one declaration onto stack */
135: break_comma = true;
136: /* while in declaration, newline should be forced after comma */
137: p_stack[++tos] = decl;
138: il[tos] = i_l_follow;
139:
140: if (ljust_decl) {
141: /* only do if we want left justified declarations */
142: ind_level = 0;
143: for (i = tos - 1; i > 0; --i)
144: if (p_stack[i] == decl)
145: ++ind_level;
146: /* indentation is number of declaration levels deep we are */
147: i_l_follow = ind_level;
148: }
149: }
150: break;
151:
152: case ifstmt: /* scanned if (...) */
153: case dolit: /* 'do' */
154: case forstmt: /* for (...) */
155: p_stack[++tos] = tk;
156: il[tos] = ind_level = i_l_follow;
157: ++i_l_follow; /* subsequent statements should be indented 1 */
158: search_brace = btype_2;
159: break;
160:
161: case lbrace: /* scanned { */
162: break_comma = false;
163: /* don't break comma in an initial list */
164: if (p_stack[tos] == stmt || p_stack[tos] == decl
165: || p_stack[tos] == stmtl)
166: ++i_l_follow; /* it is a random, isolated stmt group or a
167: declaration */
168: else {
169: if (s_code == e_code) {
170: /* only do this if there is nothing on the line */
171: --ind_level;
172: /* it is a group as part of a while, for, etc. */
173: if (p_stack[tos] == swstmt)
174: --ind_level;
175: /* for a switch, brace should be two levels out from the code
176: */
177: }
178: }
179:
180: p_stack[++tos] = lbrace;
181: il[tos] = ind_level;
182: p_stack[++tos] = stmt;
183: /* allow null stmt between braces */
184: il[tos] = i_l_follow;
185: break;
186:
187: case whilestmt: /* scanned while (...) */
188: if (p_stack[tos] == dohead) {
189: /* it is matched with do stmt */
190: ind_level = i_l_follow = il[tos];
191: p_stack[++tos] = whilestmt;
192: il[tos] = ind_level = i_l_follow;
193: }
194: else { /* it is a while loop */
195: p_stack[++tos] = whilestmt;
196: il[tos] = i_l_follow;
197: ++i_l_follow;
198: search_brace = btype_2;
199: }
200:
201: break;
202:
203: case elselit: /* scanned an else */
204:
205: if (p_stack[tos] != ifhead) {
206: printf ("%d: Unmatched else\n", line_no);
207: }
208: else {
209: ind_level = il[tos];
210: /* indentation for else should be same as for if */
211: i_l_follow = ind_level + 1;
212: /* everything following should be in 1 level */
213: p_stack[tos] = elsehead;
214: /* remember if with else */
215: search_brace = btype_2;
216: }
217:
218: break;
219:
220: case rbrace: /* scanned a } */
221: /* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */
222: if (p_stack[tos - 1] == lbrace) {
223: ind_level = i_l_follow = il[--tos];
224: p_stack[tos] = stmt;
225: }
226: else {
227: printf ("%d: Stmt nesting error\n", line_no);
228: }
229:
230: break;
231:
232: case swstmt: /* had switch (...) */
233: p_stack[++tos] = swstmt;
234: cstk[tos] = case_ind;
235: /* save current case indent level */
236: il[tos] = i_l_follow;
237: case_ind = i_l_follow + 1;
238: /* cases should be one level down from switch */
239: i_l_follow + = 2; /* statements should be two levels in */
240: search_brace = btype_2;
241: break;
242:
243: case semicolon: /* this indicates a simple stmt */
244: break_comma = false;
245: /* turn off flag to break after commas in a declaration */
246: p_stack[++tos] = stmt;
247: il[tos] = ind_level;
248: break;
249:
250: default: /* this is an error */
251: printf ("%d: Unknown code to parser - %d\n", line_no, tk);
252: return;
253:
254:
255: } /* end of switch */
256:
257: reduce (); /* see if any reduction can be done */
258: #ifdef debug
259: for (i = 1; i <= tos; ++i)
260: printf ("(%d %d)", p_stack[i], il[i]);
261: printf ("\n");
262: #endif
263: return;
264: }
265: /*
266:
267: Copyright (C) 1976
268: by the
269: Board of Trustees
270: of the
271: University of Illinois
272:
273: All rights reserved
274:
275:
276: NAME:
277: reduce
278:
279: FUNCTION:
280: Implements the reduce part of the parsing algorithm
281:
282: ALGORITHM:
283: The following reductions are done. Reductions are repeated until no
284: more are possible.
285:
286: Old___ TOS___ New___ TOS___
287: <stmt> <stmt> <stmtl>
288: <stmtl> <stmt> <stmtl>
289: do <stmt> "dostmt"
290: if <stmt> "ifstmt"
291: switch <stmt> <stmt>
292: decl <stmt> <stmt>
293: "ifelse" <stmt> <stmt>
294: for <stmt> <stmt>
295: while <stmt> <stmt>
296: "dostmt" while <stmt>
297:
298: On each reduction, i_l_follow (the indentation for the following line)
299: is set to the indentation level associated with the old TOS.
300:
301: PARAMETERS:
302: None
303:
304: RETURNS:
305: Nothing
306:
307: GLOBALS:
308: cstk
309: i_l_follow =
310: il
311: p_stack =
312: tos =
313:
314: CALLS:
315: None
316:
317: CALLED BY:
318: parse
319:
320: HISTORY:
321: initial coding November 1976 D A Willcox of CAC
322:
323: */
324: /*----------------------------------------------*\
325: | REDUCTION PHASE
326: \*----------------------------------------------*/
327: reduce () {
328:
329: register int i;
330: /* local looping variable */
331:
332: for (;;) { /* keep looping until there is nothing left to
333: reduce */
334:
335: switch (p_stack[tos]) {
336:
337: case stmt:
338: switch (p_stack[tos - 1]) {
339:
340: case stmt:
341: case stmtl:
342: /* stmtl stmt or stmt stmt */
343: p_stack[--tos] = stmtl;
344: break;
345:
346: case dolit:
347: /* <do> <stmt> */
348: p_stack[--tos] = dohead;
349: i_l_follow = il[tos];
350: break;
351:
352: case ifstmt:
353: /* <if> <stmt> */
354: p_stack[--tos] = ifhead;
355: for (i = tos - 1;
356: (
357: p_stack[i] != stmt
358: &&
359: p_stack[i] != stmtl
360: &&
361: p_stack[i] != lbrace
362: );
363: --i);
364: i_l_follow = il[i];
365: /* for the time being, we will assume that there is no else
366: on this if, and set the indentation level accordingly.
367: If an else is scanned, it will be fixed up later */
368: break;
369:
370: case swstmt:
371: /* <switch> <stmt> */
372: case_ind = cstk[tos - 1];
373:
374: case decl: /* finish of a declaration */
375: case elsehead:
376: /* <<if> <stmt> else> <stmt> */
377: case forstmt:
378: /* <for> <stmt> */
379: case whilestmt:
380: /* <while> <stmt> */
381: p_stack[--tos] = stmt;
382: i_l_follow = il[tos];
383: break;
384:
385: default: /* <anything else> <stmt> */
386: return;
387:
388: } /* end of section for <stmt> on top of stack */
389: break;
390:
391: case whilestmt: /* while (...) on top */
392: if (p_stack[tos - 1] == dohead) {
393: /* it is termination of a do while */
394: p_stack[--tos] = stmt;
395: break;
396: }
397: else
398: return;
399:
400: default: /* anything else on top */
401: return;
402:
403: } /* end of big switch */
404:
405: } /* end of reduction phase for (;;) */
406: }
Defined functions
parse
defined in line
112; used 11 times
- in /usr/src/ucb/indent/indent.c line
316,
589,
620,
740,
751,
780,
798,
831,
860,
866,
899
Defined variables
cstk
defined in line
108; used 2 times
il
defined in line
107; used 15 times
- in line 138,
156,
181-184(2),
190-196(3),
209,
223,
236,
247,
260,
349,
364,
382
p_stack
defined in line
105; used 33 times
- in line 120-122(2),
133-137(2),
144,
155,
164-165(3),
173,
180-182(2),
188-195(3),
205,
213,
222-224(2),
233,
246,
260,
335-348(4),
354-361(4),
381,
392-394(2)
sccsid
defined in line
1;
never used
tos
defined in line
109; used 46 times
- in line 120-122(2),
133-143(4),
155-156(2),
164-165(3),
173,
180-196(10),
205-213(3),
222-224(3),
233-236(3),
246-247(2),
259,
335-355(7),
372,
381-382(2),
392-394(2)