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

Defined functions

parse defined in line 62; used 12 times
reduce defined in line 255; used 2 times

Defined variables

sccsid defined in line 8; never used
Last modified: 1985-09-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1038
Valid CSS Valid XHTML 1.0 Strict