Annotation of 43BSD/ucb/indent/parse.c, revision 1.1.1.1

1.1       root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.