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.
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.
30 int tk
; /* the code for the construct
36 printf("%2d - %s\n", tk
, token
);
39 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 ::=
44 reduce(); /* see if this allows any
50 { /* go on and figure out what to
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
59 break_comma
= true; /* while in declaration,
60 newline should be forced
62 ps
.p_stack
[++ps
.tos
] = decl
;
63 ps
.il
[ps
.tos
] = ps
.i_l_follow
;
66 { /* only do if we want left
67 justified declarations */
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
74 ps
.i_l_follow
= ps
.ind_level
;
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
88 ps
.search_brace
= btype_2
;
91 case lbrace
: /* scanned { */
92 break_comma
= false; /* don't break comma in an
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 */
100 if (s_code
== e_code
)
102 /* only do this if there is nothing on the line */
104 /* it is a group as part of a while, for, etc. */
105 if (ps
.p_stack
[ps
.tos
] == swstmt
&& ps
.case_indent
>= 1)
107 /* for a switch, brace should be two levels out from the
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
;
119 case whilestmt
: /* scanned while (...) */
120 if (ps
.p_stack
[ps
.tos
] == dohead
)
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
;
127 { /* it is a while loop */
128 ps
.p_stack
[++ps
.tos
] = whilestmt
;
129 ps
.il
[ps
.tos
] = ps
.i_l_follow
;
131 ps
.search_brace
= btype_2
;
136 case elselit
: /* scanned an else */
138 if (ps
.p_stack
[ps
.tos
] != ifhead
)
139 diag(1, "Unmatched 'else'");
142 ps
.ind_level
= ps
.il
[ps
.tos
]; /* indentation for else should
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
;
152 case rbrace
: /* scanned a } */
153 /* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */
154 if (ps
.p_stack
[ps
.tos
- 1] == lbrace
)
156 ps
.ind_level
= ps
.i_l_follow
= ps
.il
[--ps
.tos
];
157 ps
.p_stack
[ps
.tos
] = stmt
;
159 diag(1, "Stmt nesting error.");
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
170 ps
.i_l_follow
+= ps
.case_indent
+ 1; /* statements should be
172 ps
.search_brace
= btype_2
;
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
;
182 default: /* this is an error */
183 diag(1, "Unknown code to parser");
187 } /* end of switch */
189 reduce(); /* see if any reduction can be
193 for (i
= 1; i
<= ps
.tos
; ++i
)
194 printf("(%d %d)", ps
.p_stack
[i
], ps
.il
[i
]);
202 * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
204 * All rights reserved
209 * FUNCTION: Implements the reduce part of the parsing algorithm
211 * ALGORITHM: The following reductions are done. Reductions are repeated until
212 * no more are possible.
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>
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.
226 * GLOBALS: ps.cstk ps.i_l_follow = ps.il ps.p_stack = ps.tos =
232 * HISTORY: initial coding November 1976 D A Willcox of CAC
235 /*----------------------------------------------*\
237 \*----------------------------------------------*/
244 { /* keep looping until there is
245 nothing left to reduce */
247 switch (ps
.p_stack
[ps
.tos
])
251 switch (ps
.p_stack
[ps
.tos
- 1])
256 /* stmtl stmt or stmt stmt */
257 ps
.p_stack
[--ps
.tos
] = stmtl
;
260 case dolit
: /* <do> <stmt> */
261 ps
.p_stack
[--ps
.tos
] = dohead
;
262 ps
.i_l_follow
= ps
.il
[ps
.tos
];
267 ps
.p_stack
[--ps
.tos
] = ifhead
;
270 ps
.p_stack
[i
] != stmt
272 ps
.p_stack
[i
] != stmtl
274 ps
.p_stack
[i
] != lbrace
277 ps
.i_l_follow
= ps
.il
[i
];
278 /* for the time being, we will assume that there is no else
279 on this if, and set the indentation level accordingly.
280 If an else is scanned, it will be fixed up later */
284 /* <switch> <stmt> */
285 case_ind
= ps
.cstk
[ps
.tos
- 1];
287 case decl
: /* finish of a declaration */
289 /* <<if> <stmt> else> <stmt> */
294 ps
.p_stack
[--ps
.tos
] = stmt
;
295 ps
.i_l_follow
= ps
.il
[ps
.tos
];
298 default: /* <anything else> <stmt> */
301 } /* end of section for <stmt> on
305 case whilestmt
: /* while (...) on top */
306 if (ps
.p_stack
[ps
.tos
- 1] == dohead
)
308 /* it is termination of a do while */
309 ps
.p_stack
[--ps
.tos
] = stmt
;
314 default: /* anything else on top */