[BACK]Return to mkpar.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / yacc

Annotation of src/usr.bin/yacc/mkpar.c, Revision 1.4

1.4     ! deraadt     1: /*     $OpenBSD: mkpar.c,v 1.3 1996/03/31 04:56:02 etheisen Exp $      */
        !             2:
        !             3: /*     $NetBSD: mkpar.c,v 1.4 1996/03/19 03:21:39 jtc Exp $    */
        !             4:
        !             5: /*
        !             6:  * Copyright (c) 1989 The Regents of the University of California.
        !             7:  * All rights reserved.
        !             8:  *
        !             9:  * This code is derived from software contributed to Berkeley by
        !            10:  * Robert Paul Corbett.
        !            11:  *
        !            12:  * Redistribution and use in source and binary forms, with or without
        !            13:  * modification, are permitted provided that the following conditions
        !            14:  * are met:
        !            15:  * 1. Redistributions of source code must retain the above copyright
        !            16:  *    notice, this list of conditions and the following disclaimer.
        !            17:  * 2. Redistributions in binary form must reproduce the above copyright
        !            18:  *    notice, this list of conditions and the following disclaimer in the
        !            19:  *    documentation and/or other materials provided with the distribution.
        !            20:  * 3. All advertising materials mentioning features or use of this software
        !            21:  *    must display the following acknowledgement:
        !            22:  *     This product includes software developed by the University of
        !            23:  *     California, Berkeley and its contributors.
        !            24:  * 4. Neither the name of the University nor the names of its contributors
        !            25:  *    may be used to endorse or promote products derived from this software
        !            26:  *    without specific prior written permission.
        !            27:  *
        !            28:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            29:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            30:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            31:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            32:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            33:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            34:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            35:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            36:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            37:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            38:  * SUCH DAMAGE.
        !            39:  */
1.3       etheisen   40:
1.1       deraadt    41: #ifndef lint
1.4     ! deraadt    42: #if 0
        !            43: static char sccsid[] = "@(#)mkpar.c    5.3 (Berkeley) 1/20/91";
        !            44: #else
        !            45: static char rcsid[] = "$NetBSD: mkpar.c,v 1.4 1996/03/19 03:21:39 jtc Exp $";
        !            46: #endif
1.1       deraadt    47: #endif /* not lint */
                     48:
                     49: #include "defs.h"
                     50:
                     51: action **parser;
                     52: int SRtotal;
1.2       etheisen   53: int SRexpect = 0;
1.1       deraadt    54: int RRtotal;
                     55: short *SRconflicts;
                     56: short *RRconflicts;
                     57: short *defred;
                     58: short *rules_used;
                     59: short nunused;
                     60: short final_state;
                     61:
                     62: static int SRcount;
                     63: static int RRcount;
                     64:
                     65: extern action *parse_actions();
                     66: extern action *get_shifts();
                     67: extern action *add_reductions();
                     68: extern action *add_reduce();
                     69:
                     70:
                     71: make_parser()
                     72: {
                     73:     register int i;
                     74:
                     75:     parser = NEW2(nstates, action *);
                     76:     for (i = 0; i < nstates; i++)
                     77:        parser[i] = parse_actions(i);
                     78:
                     79:     find_final_state();
                     80:     remove_conflicts();
                     81:     unused_rules();
                     82:     if (SRtotal + RRtotal > 0) total_conflicts();
                     83:     defreds();
                     84: }
                     85:
                     86:
                     87: action *
                     88: parse_actions(stateno)
                     89: register int stateno;
                     90: {
                     91:     register action *actions;
                     92:
                     93:     actions = get_shifts(stateno);
                     94:     actions = add_reductions(stateno, actions);
                     95:     return (actions);
                     96: }
                     97:
                     98:
                     99: action *
                    100: get_shifts(stateno)
                    101: int stateno;
                    102: {
                    103:     register action *actions, *temp;
                    104:     register shifts *sp;
                    105:     register short *to_state;
                    106:     register int i, k;
                    107:     register int symbol;
                    108:
                    109:     actions = 0;
                    110:     sp = shift_table[stateno];
                    111:     if (sp)
                    112:     {
                    113:        to_state = sp->shift;
                    114:        for (i = sp->nshifts - 1; i >= 0; i--)
                    115:        {
                    116:            k = to_state[i];
                    117:            symbol = accessing_symbol[k];
                    118:            if (ISTOKEN(symbol))
                    119:            {
                    120:                temp = NEW(action);
                    121:                temp->next = actions;
                    122:                temp->symbol = symbol;
                    123:                temp->number = k;
                    124:                temp->prec = symbol_prec[symbol];
                    125:                temp->action_code = SHIFT;
                    126:                temp->assoc = symbol_assoc[symbol];
                    127:                actions = temp;
                    128:            }
                    129:        }
                    130:     }
                    131:     return (actions);
                    132: }
                    133:
                    134: action *
                    135: add_reductions(stateno, actions)
                    136: int stateno;
                    137: register action *actions;
                    138: {
                    139:     register int i, j, m, n;
                    140:     register int ruleno, tokensetsize;
                    141:     register unsigned *rowp;
                    142:
                    143:     tokensetsize = WORDSIZE(ntokens);
                    144:     m = lookaheads[stateno];
                    145:     n = lookaheads[stateno + 1];
                    146:     for (i = m; i < n; i++)
                    147:     {
                    148:        ruleno = LAruleno[i];
                    149:        rowp = LA + i * tokensetsize;
                    150:        for (j = ntokens - 1; j >= 0; j--)
                    151:        {
                    152:            if (BIT(rowp, j))
                    153:                actions = add_reduce(actions, ruleno, j);
                    154:        }
                    155:     }
                    156:     return (actions);
                    157: }
                    158:
                    159:
                    160: action *
                    161: add_reduce(actions, ruleno, symbol)
                    162: register action *actions;
                    163: register int ruleno, symbol;
                    164: {
                    165:     register action *temp, *prev, *next;
                    166:
                    167:     prev = 0;
                    168:     for (next = actions; next && next->symbol < symbol; next = next->next)
                    169:        prev = next;
                    170:
                    171:     while (next && next->symbol == symbol && next->action_code == SHIFT)
                    172:     {
                    173:        prev = next;
                    174:        next = next->next;
                    175:     }
                    176:
                    177:     while (next && next->symbol == symbol &&
                    178:            next->action_code == REDUCE && next->number < ruleno)
                    179:     {
                    180:        prev = next;
                    181:        next = next->next;
                    182:     }
                    183:
                    184:     temp = NEW(action);
                    185:     temp->next = next;
                    186:     temp->symbol = symbol;
                    187:     temp->number = ruleno;
                    188:     temp->prec = rprec[ruleno];
                    189:     temp->action_code = REDUCE;
                    190:     temp->assoc = rassoc[ruleno];
                    191:
                    192:     if (prev)
                    193:        prev->next = temp;
                    194:     else
                    195:        actions = temp;
                    196:
                    197:     return (actions);
                    198: }
                    199:
                    200:
                    201: find_final_state()
                    202: {
                    203:     register int goal, i;
                    204:     register short *to_state;
                    205:     register shifts *p;
                    206:
                    207:     p = shift_table[0];
                    208:     to_state = p->shift;
                    209:     goal = ritem[1];
                    210:     for (i = p->nshifts - 1; i >= 0; --i)
                    211:     {
                    212:        final_state = to_state[i];
                    213:        if (accessing_symbol[final_state] == goal) break;
                    214:     }
                    215: }
                    216:
                    217:
                    218: unused_rules()
                    219: {
                    220:     register int i;
                    221:     register action *p;
                    222:
                    223:     rules_used = (short *) MALLOC(nrules*sizeof(short));
                    224:     if (rules_used == 0) no_space();
                    225:
                    226:     for (i = 0; i < nrules; ++i)
                    227:        rules_used[i] = 0;
                    228:
                    229:     for (i = 0; i < nstates; ++i)
                    230:     {
                    231:        for (p = parser[i]; p; p = p->next)
                    232:        {
                    233:            if (p->action_code == REDUCE && p->suppressed == 0)
                    234:                rules_used[p->number] = 1;
                    235:        }
                    236:     }
                    237:
                    238:     nunused = 0;
                    239:     for (i = 3; i < nrules; ++i)
                    240:        if (!rules_used[i]) ++nunused;
                    241:
                    242:     if (nunused)
                    243:        if (nunused == 1)
                    244:            fprintf(stderr, "%s: 1 rule never reduced\n", myname);
                    245:        else
                    246:            fprintf(stderr, "%s: %d rules never reduced\n", myname, nunused);
                    247: }
                    248:
                    249:
                    250: remove_conflicts()
                    251: {
                    252:     register int i;
                    253:     register int symbol;
                    254:     register action *p, *pref;
                    255:
                    256:     SRtotal = 0;
                    257:     RRtotal = 0;
                    258:     SRconflicts = NEW2(nstates, short);
                    259:     RRconflicts = NEW2(nstates, short);
                    260:     for (i = 0; i < nstates; i++)
                    261:     {
                    262:        SRcount = 0;
                    263:        RRcount = 0;
                    264:        symbol = -1;
                    265:        for (p = parser[i]; p; p = p->next)
                    266:        {
                    267:            if (p->symbol != symbol)
                    268:            {
                    269:                pref = p;
                    270:                symbol = p->symbol;
                    271:            }
                    272:            else if (i == final_state && symbol == 0)
                    273:            {
                    274:                SRcount++;
                    275:                p->suppressed = 1;
                    276:            }
                    277:            else if (pref->action_code == SHIFT)
                    278:            {
                    279:                if (pref->prec > 0 && p->prec > 0)
                    280:                {
                    281:                    if (pref->prec < p->prec)
                    282:                    {
                    283:                        pref->suppressed = 2;
                    284:                        pref = p;
                    285:                    }
                    286:                    else if (pref->prec > p->prec)
                    287:                    {
                    288:                        p->suppressed = 2;
                    289:                    }
                    290:                    else if (pref->assoc == LEFT)
                    291:                    {
                    292:                        pref->suppressed = 2;
                    293:                        pref = p;
                    294:                    }
                    295:                    else if (pref->assoc == RIGHT)
                    296:                    {
                    297:                        p->suppressed = 2;
                    298:                    }
                    299:                    else
                    300:                    {
                    301:                        pref->suppressed = 2;
                    302:                        p->suppressed = 2;
                    303:                    }
                    304:                }
                    305:                else
                    306:                {
                    307:                    SRcount++;
                    308:                    p->suppressed = 1;
                    309:                }
                    310:            }
                    311:            else
                    312:            {
                    313:                RRcount++;
                    314:                p->suppressed = 1;
                    315:            }
                    316:        }
                    317:        SRtotal += SRcount;
                    318:        RRtotal += RRcount;
                    319:        SRconflicts[i] = SRcount;
                    320:        RRconflicts[i] = RRcount;
                    321:     }
                    322: }
                    323:
                    324:
                    325: total_conflicts()
                    326: {
1.2       etheisen  327:     /* Warn if s/r != expect or if any r/r */
                    328:     if ((SRtotal != SRexpect) || RRtotal)
                    329:     {
                    330:         if (SRtotal == 1)
                    331:             fprintf(stderr, "%s: 1 shift/reduce conflict\n", myname);
                    332:         else if (SRtotal > 1)
                    333:             fprintf(stderr, "%s: %d shift/reduce conflicts\n", myname,
                    334:                     SRtotal);
                    335:     }
1.1       deraadt   336:
                    337:     if (RRtotal == 1)
1.2       etheisen  338:         fprintf(stderr, "%s: 1 reduce/reduce conflict\n", myname);
1.1       deraadt   339:     else if (RRtotal > 1)
1.2       etheisen  340:        fprintf(stderr, "%s: %d reduce/reduce conflicts\n", myname,
                    341:                 RRtotal);
1.1       deraadt   342: }
                    343:
                    344:
                    345: int
                    346: sole_reduction(stateno)
                    347: int stateno;
                    348: {
                    349:     register int count, ruleno;
                    350:     register action *p;
                    351:
                    352:     count = 0;
                    353:     ruleno = 0;
                    354:     for (p = parser[stateno]; p; p = p->next)
                    355:     {
                    356:        if (p->action_code == SHIFT && p->suppressed == 0)
                    357:            return (0);
                    358:        else if (p->action_code == REDUCE && p->suppressed == 0)
                    359:        {
                    360:            if (ruleno > 0 && p->number != ruleno)
                    361:                return (0);
                    362:            if (p->symbol != 1)
                    363:                ++count;
                    364:            ruleno = p->number;
                    365:        }
                    366:     }
                    367:
                    368:     if (count == 0)
                    369:        return (0);
                    370:     return (ruleno);
                    371: }
                    372:
                    373:
                    374: defreds()
                    375: {
                    376:     register int i;
                    377:
                    378:     defred = NEW2(nstates, short);
                    379:     for (i = 0; i < nstates; i++)
                    380:        defred[i] = sole_reduction(i);
                    381: }
                    382:
                    383: free_action_row(p)
                    384: register action *p;
                    385: {
                    386:   register action *q;
                    387:
                    388:   while (p)
                    389:     {
                    390:       q = p->next;
                    391:       FREE(p);
                    392:       p = q;
                    393:     }
                    394: }
                    395:
                    396: free_parser()
                    397: {
                    398:   register int i;
                    399:
                    400:   for (i = 0; i < nstates; i++)
                    401:     free_action_row(parser[i]);
                    402:
                    403:   FREE(parser);
                    404: }