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