|
|
1.1 ! root 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: (1) source distributions retain this entire copyright ! 9: * notice and comment, and (2) distributions including binaries display ! 10: * the following acknowledgement: ``This product includes software ! 11: * developed by the University of California, Berkeley and its contributors'' ! 12: * in the documentation or other materials provided with the distribution ! 13: * and in all advertising materials mentioning features or use of this ! 14: * software. Neither the name of the University nor the names of its ! 15: * contributors may be used to endorse or promote products derived ! 16: * from this software without specific prior written permission. ! 17: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 18: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 19: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 20: */ ! 21: ! 22: #ifndef lint ! 23: static char sccsid[] = "@(#)parse.c 5.11 (Berkeley) 6/1/90"; ! 24: #endif /* not lint */ ! 25: ! 26: #include "indent_globs.h" ! 27: #include "indent_codes.h" ! 28: ! 29: parse(tk) ! 30: int tk; /* the code for the construct scanned */ ! 31: { ! 32: int i; ! 33: ! 34: #ifdef debug ! 35: printf("%2d - %s\n", tk, token); ! 36: #endif ! 37: ! 38: while (ps.p_stack[ps.tos] == ifhead && tk != elselit) { ! 39: /* true if we have an if without an else */ ! 40: ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::= stmt ! 41: * reduction */ ! 42: reduce(); /* see if this allows any reduction */ ! 43: } ! 44: ! 45: ! 46: switch (tk) { /* go on and figure out what to do with the ! 47: * input */ ! 48: ! 49: case decl: /* scanned a declaration word */ ! 50: ps.search_brace = btype_2; ! 51: /* indicate that following brace should be on same line */ ! 52: if (ps.p_stack[ps.tos] != decl) { /* only put one declaration ! 53: * onto stack */ ! 54: break_comma = true; /* while in declaration, newline should be ! 55: * forced after comma */ ! 56: ps.p_stack[++ps.tos] = decl; ! 57: ps.il[ps.tos] = ps.i_l_follow; ! 58: ! 59: if (ps.ljust_decl) {/* only do if we want left justified ! 60: * declarations */ ! 61: ps.ind_level = 0; ! 62: for (i = ps.tos - 1; i > 0; --i) ! 63: if (ps.p_stack[i] == decl) ! 64: ++ps.ind_level; /* indentation is number of ! 65: * declaration levels deep we are */ ! 66: ps.i_l_follow = ps.ind_level; ! 67: } ! 68: } ! 69: break; ! 70: ! 71: case ifstmt: /* scanned if (...) */ ! 72: if (ps.p_stack[ps.tos] == elsehead && ps.else_if) /* "else if ..." */ ! 73: ps.i_l_follow = ps.il[ps.tos]; ! 74: case dolit: /* 'do' */ ! 75: case forstmt: /* for (...) */ ! 76: ps.p_stack[++ps.tos] = tk; ! 77: ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; ! 78: ++ps.i_l_follow; /* subsequent statements should be indented 1 */ ! 79: ps.search_brace = btype_2; ! 80: break; ! 81: ! 82: case lbrace: /* scanned { */ ! 83: break_comma = false; /* don't break comma in an initial list */ ! 84: if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl ! 85: || ps.p_stack[ps.tos] == stmtl) ! 86: ++ps.i_l_follow; /* it is a random, isolated stmt group or a ! 87: * declaration */ ! 88: else { ! 89: if (s_code == e_code) { ! 90: /* ! 91: * only do this if there is nothing on the line ! 92: */ ! 93: --ps.ind_level; ! 94: /* ! 95: * it is a group as part of a while, for, etc. ! 96: */ ! 97: if (ps.p_stack[ps.tos] == swstmt && ps.case_indent >= 1) ! 98: --ps.ind_level; ! 99: /* ! 100: * for a switch, brace should be two levels out from the code ! 101: */ ! 102: } ! 103: } ! 104: ! 105: ps.p_stack[++ps.tos] = lbrace; ! 106: ps.il[ps.tos] = ps.ind_level; ! 107: ps.p_stack[++ps.tos] = stmt; ! 108: /* allow null stmt between braces */ ! 109: ps.il[ps.tos] = ps.i_l_follow; ! 110: break; ! 111: ! 112: case whilestmt: /* scanned while (...) */ ! 113: if (ps.p_stack[ps.tos] == dohead) { ! 114: /* it is matched with do stmt */ ! 115: ps.ind_level = ps.i_l_follow = ps.il[ps.tos]; ! 116: ps.p_stack[++ps.tos] = whilestmt; ! 117: ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; ! 118: } ! 119: else { /* it is a while loop */ ! 120: ps.p_stack[++ps.tos] = whilestmt; ! 121: ps.il[ps.tos] = ps.i_l_follow; ! 122: ++ps.i_l_follow; ! 123: ps.search_brace = btype_2; ! 124: } ! 125: ! 126: break; ! 127: ! 128: case elselit: /* scanned an else */ ! 129: ! 130: if (ps.p_stack[ps.tos] != ifhead) ! 131: diag(1, "Unmatched 'else'"); ! 132: else { ! 133: ps.ind_level = ps.il[ps.tos]; /* indentation for else should ! 134: * be same as for if */ ! 135: ps.i_l_follow = ps.ind_level + 1; /* everything following should ! 136: * be in 1 level */ ! 137: ps.p_stack[ps.tos] = elsehead; ! 138: /* remember if with else */ ! 139: ps.search_brace = btype_2 | ps.else_if; ! 140: } ! 141: break; ! 142: ! 143: case rbrace: /* scanned a } */ ! 144: /* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */ ! 145: if (ps.p_stack[ps.tos - 1] == lbrace) { ! 146: ps.ind_level = ps.i_l_follow = ps.il[--ps.tos]; ! 147: ps.p_stack[ps.tos] = stmt; ! 148: } ! 149: else ! 150: diag(1, "Stmt nesting error."); ! 151: break; ! 152: ! 153: case swstmt: /* had switch (...) */ ! 154: ps.p_stack[++ps.tos] = swstmt; ! 155: ps.cstk[ps.tos] = case_ind; ! 156: /* save current case indent level */ ! 157: ps.il[ps.tos] = ps.i_l_follow; ! 158: case_ind = ps.i_l_follow + ps.case_indent; /* cases should be one ! 159: * level down from ! 160: * switch */ ! 161: ps.i_l_follow += ps.case_indent + 1; /* statements should be two ! 162: * levels in */ ! 163: ps.search_brace = btype_2; ! 164: break; ! 165: ! 166: case semicolon: /* this indicates a simple stmt */ ! 167: break_comma = false; /* turn off flag to break after commas in a ! 168: * declaration */ ! 169: ps.p_stack[++ps.tos] = stmt; ! 170: ps.il[ps.tos] = ps.ind_level; ! 171: break; ! 172: ! 173: default: /* this is an error */ ! 174: diag(1, "Unknown code to parser"); ! 175: return; ! 176: ! 177: ! 178: } /* end of switch */ ! 179: ! 180: reduce(); /* see if any reduction can be done */ ! 181: ! 182: #ifdef debug ! 183: for (i = 1; i <= ps.tos; ++i) ! 184: printf("(%d %d)", ps.p_stack[i], ps.il[i]); ! 185: printf("\n"); ! 186: #endif ! 187: ! 188: return; ! 189: } ! 190: ! 191: /* ! 192: * NAME: reduce ! 193: * ! 194: * FUNCTION: Implements the reduce part of the parsing algorithm ! 195: * ! 196: * ALGORITHM: The following reductions are done. Reductions are repeated ! 197: * until no more are possible. ! 198: * ! 199: * Old TOS New TOS ! 200: * <stmt> <stmt> <stmtl> ! 201: * <stmtl> <stmt> <stmtl> ! 202: * do <stmt> "dostmt" ! 203: * if <stmt> "ifstmt" ! 204: * switch <stmt> <stmt> ! 205: * decl <stmt> <stmt> ! 206: * "ifelse" <stmt> <stmt> ! 207: * for <stmt> <stmt> ! 208: * while <stmt> <stmt> ! 209: * "dostmt" while <stmt> ! 210: * ! 211: * On each reduction, ps.i_l_follow (the indentation for the following line) ! 212: * is 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.