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 #ifndef lint 22 static char sccsid[] = "@(#)parse.c 5.8 (Berkeley) 09/15/88"; 23 #endif /* not lint */ 24 25 #include "./indent_globs.h" 26 #include "./indent_codes.h" 27 28 29 30 31 parse(tk) 32 int tk; /* the code for the construct scanned */ 33 { 34 int i; 35 36 #ifdef debug 37 printf("%2d - %s\n", tk, token); 38 #endif 39 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 43 * reduction */ 44 reduce(); /* see if this allows any reduction */ 45 } 46 47 48 switch (tk) { /* go on and figure out what to do with the 49 * input */ 50 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; 59 ps.il[ps.tos] = ps.i_l_follow; 60 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; 69 } 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 */ 104 } 105 } 106 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 } 127 128 break; 129 130 case elselit: /* scanned an else */ 131 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; 144 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 161 * level down from 162 * switch */ 163 ps.i_l_follow += ps.case_indent + 1; /* statements should be two 164 * levels in */ 165 ps.search_brace = btype_2; 166 break; 167 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; 174 175 default: /* this is an error */ 176 diag(1, "Unknown code to parser"); 177 return; 178 179 180 } /* end of switch */ 181 182 reduce(); /* see if any reduction can be done */ 183 184 #ifdef debug 185 for (i = 1; i <= ps.tos; ++i) 186 printf("(%d %d)", ps.p_stack[i], ps.il[i]); 187 printf("\n"); 188 #endif 189 190 return; 191 } 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 * 206 * Old TOS New TOS <stmt> <stmt> <stmtl> <stmtl> <stmt> <stmtl> do 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 * 211 * On each reduction, ps.i_l_follow (the indentation for the following line) is 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 * 222 * CALLED BY: parse 223 * 224 * HISTORY: initial coding November 1976 D A Willcox of CAC 225 * 226 */ 227 /*----------------------------------------------*\ 228 | REDUCTION PHASE | 229 \*----------------------------------------------*/ 230 reduce() 231 { 232 233 register int i; 234 235 for (;;) { /* keep looping until there is nothing left to 236 * reduce */ 237 238 switch (ps.p_stack[ps.tos]) { 239 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; 247 break; 248 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; 273 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 302 return; 303 304 default: /* anything else on top */ 305 return; 306 307 } 308 } 309 } 310