# 2.11BSD#431 - /usr/src/ucb/indent/parse.c

##### Functions

    parse             X
    reduce            X

       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

- in /usr/src/ucb/indent/indent.c line 204, 481, 514, 679, 688, 720, 741, 775, 810, 822, 828, 876

reduce defined in line 255; used 2 times

- in line 74, 210

#### Defined variables

sccsid defined in line 8; never used

Last modified: 1987-02-17 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1116 |