Annotation of 42BSD/ucb/indent/parse.c, revision 1.1

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

unix.superglobalmegacorp.com

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