Annotation of 43BSD/ucb/indent/parse.c, revision 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.