Annotation of 43BSDTahoe/ucb/indent/parse.c, revision 1.1

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

unix.superglobalmegacorp.com

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