[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.7

1.7     ! mpech       1: /*     $OpenBSD: mkpar.c,v 1.6 2001/07/16 06:29:44 pvalchev Exp $      */
1.4       deraadt     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:
1.6       pvalchev   70: int sole_reduction __P((int));
                     71: void free_action_row __P((action *));
1.1       deraadt    72:
1.6       pvalchev   73: void find_final_state __P((void));
                     74: void unused_rules __P((void));
                     75: void remove_conflicts __P((void));
                     76: void total_conflicts __P((void));
                     77: void defreds __P((void));
                     78:
                     79:
                     80: void
1.1       deraadt    81: make_parser()
                     82: {
1.7     ! mpech      83:     int i;
1.1       deraadt    84:
                     85:     parser = NEW2(nstates, action *);
                     86:     for (i = 0; i < nstates; i++)
                     87:        parser[i] = parse_actions(i);
                     88:
                     89:     find_final_state();
                     90:     remove_conflicts();
                     91:     unused_rules();
                     92:     if (SRtotal + RRtotal > 0) total_conflicts();
                     93:     defreds();
                     94: }
                     95:
                     96:
                     97: action *
                     98: parse_actions(stateno)
1.7     ! mpech      99: int stateno;
1.1       deraadt   100: {
1.7     ! mpech     101:     action *actions;
1.1       deraadt   102:
                    103:     actions = get_shifts(stateno);
                    104:     actions = add_reductions(stateno, actions);
                    105:     return (actions);
                    106: }
                    107:
                    108:
                    109: action *
                    110: get_shifts(stateno)
                    111: int stateno;
                    112: {
1.7     ! mpech     113:     action *actions, *temp;
        !           114:     shifts *sp;
        !           115:     short *to_state;
        !           116:     int i, k;
        !           117:     int symbol;
1.1       deraadt   118:
                    119:     actions = 0;
                    120:     sp = shift_table[stateno];
                    121:     if (sp)
                    122:     {
                    123:        to_state = sp->shift;
                    124:        for (i = sp->nshifts - 1; i >= 0; i--)
                    125:        {
                    126:            k = to_state[i];
                    127:            symbol = accessing_symbol[k];
                    128:            if (ISTOKEN(symbol))
                    129:            {
                    130:                temp = NEW(action);
                    131:                temp->next = actions;
                    132:                temp->symbol = symbol;
                    133:                temp->number = k;
                    134:                temp->prec = symbol_prec[symbol];
                    135:                temp->action_code = SHIFT;
                    136:                temp->assoc = symbol_assoc[symbol];
                    137:                actions = temp;
                    138:            }
                    139:        }
                    140:     }
                    141:     return (actions);
                    142: }
                    143:
                    144: action *
                    145: add_reductions(stateno, actions)
                    146: int stateno;
1.7     ! mpech     147: action *actions;
1.1       deraadt   148: {
1.7     ! mpech     149:     int i, j, m, n;
        !           150:     int ruleno, tokensetsize;
        !           151:     unsigned *rowp;
1.1       deraadt   152:
                    153:     tokensetsize = WORDSIZE(ntokens);
                    154:     m = lookaheads[stateno];
                    155:     n = lookaheads[stateno + 1];
                    156:     for (i = m; i < n; i++)
                    157:     {
                    158:        ruleno = LAruleno[i];
                    159:        rowp = LA + i * tokensetsize;
                    160:        for (j = ntokens - 1; j >= 0; j--)
                    161:        {
                    162:            if (BIT(rowp, j))
                    163:                actions = add_reduce(actions, ruleno, j);
                    164:        }
                    165:     }
                    166:     return (actions);
                    167: }
                    168:
                    169:
                    170: action *
                    171: add_reduce(actions, ruleno, symbol)
1.7     ! mpech     172: action *actions;
        !           173: int ruleno, symbol;
1.1       deraadt   174: {
1.7     ! mpech     175:     action *temp, *prev, *next;
1.1       deraadt   176:
                    177:     prev = 0;
                    178:     for (next = actions; next && next->symbol < symbol; next = next->next)
                    179:        prev = next;
                    180:
                    181:     while (next && next->symbol == symbol && next->action_code == SHIFT)
                    182:     {
                    183:        prev = next;
                    184:        next = next->next;
                    185:     }
                    186:
                    187:     while (next && next->symbol == symbol &&
                    188:            next->action_code == REDUCE && next->number < ruleno)
                    189:     {
                    190:        prev = next;
                    191:        next = next->next;
                    192:     }
                    193:
                    194:     temp = NEW(action);
                    195:     temp->next = next;
                    196:     temp->symbol = symbol;
                    197:     temp->number = ruleno;
                    198:     temp->prec = rprec[ruleno];
                    199:     temp->action_code = REDUCE;
                    200:     temp->assoc = rassoc[ruleno];
                    201:
                    202:     if (prev)
                    203:        prev->next = temp;
                    204:     else
                    205:        actions = temp;
                    206:
                    207:     return (actions);
                    208: }
                    209:
                    210:
1.6       pvalchev  211: void
1.1       deraadt   212: find_final_state()
                    213: {
1.7     ! mpech     214:     int goal, i;
        !           215:     short *to_state;
        !           216:     shifts *p;
1.1       deraadt   217:
                    218:     p = shift_table[0];
                    219:     to_state = p->shift;
                    220:     goal = ritem[1];
                    221:     for (i = p->nshifts - 1; i >= 0; --i)
                    222:     {
                    223:        final_state = to_state[i];
                    224:        if (accessing_symbol[final_state] == goal) break;
                    225:     }
                    226: }
                    227:
                    228:
1.6       pvalchev  229: void
1.1       deraadt   230: unused_rules()
                    231: {
1.7     ! mpech     232:     int i;
        !           233:     action *p;
1.1       deraadt   234:
                    235:     rules_used = (short *) MALLOC(nrules*sizeof(short));
                    236:     if (rules_used == 0) no_space();
                    237:
                    238:     for (i = 0; i < nrules; ++i)
                    239:        rules_used[i] = 0;
                    240:
                    241:     for (i = 0; i < nstates; ++i)
                    242:     {
                    243:        for (p = parser[i]; p; p = p->next)
                    244:        {
                    245:            if (p->action_code == REDUCE && p->suppressed == 0)
                    246:                rules_used[p->number] = 1;
                    247:        }
                    248:     }
                    249:
                    250:     nunused = 0;
                    251:     for (i = 3; i < nrules; ++i)
                    252:        if (!rules_used[i]) ++nunused;
                    253:
1.6       pvalchev  254:     if (nunused) {
1.1       deraadt   255:        if (nunused == 1)
1.5       millert   256:            fprintf(stderr, "%s: 1 rule never reduced\n", __progname);
1.1       deraadt   257:        else
1.5       millert   258:            fprintf(stderr, "%s: %d rules never reduced\n", __progname,
                    259:                    nunused);
1.6       pvalchev  260:     }
1.1       deraadt   261: }
                    262:
                    263:
1.6       pvalchev  264: void
1.1       deraadt   265: remove_conflicts()
                    266: {
1.7     ! mpech     267:     int i;
        !           268:     int symbol;
        !           269:     action *p, *pref;
1.1       deraadt   270:
                    271:     SRtotal = 0;
                    272:     RRtotal = 0;
                    273:     SRconflicts = NEW2(nstates, short);
                    274:     RRconflicts = NEW2(nstates, short);
                    275:     for (i = 0; i < nstates; i++)
                    276:     {
                    277:        SRcount = 0;
                    278:        RRcount = 0;
                    279:        symbol = -1;
                    280:        for (p = parser[i]; p; p = p->next)
                    281:        {
                    282:            if (p->symbol != symbol)
                    283:            {
                    284:                pref = p;
                    285:                symbol = p->symbol;
                    286:            }
                    287:            else if (i == final_state && symbol == 0)
                    288:            {
                    289:                SRcount++;
                    290:                p->suppressed = 1;
                    291:            }
                    292:            else if (pref->action_code == SHIFT)
                    293:            {
                    294:                if (pref->prec > 0 && p->prec > 0)
                    295:                {
                    296:                    if (pref->prec < p->prec)
                    297:                    {
                    298:                        pref->suppressed = 2;
                    299:                        pref = p;
                    300:                    }
                    301:                    else if (pref->prec > p->prec)
                    302:                    {
                    303:                        p->suppressed = 2;
                    304:                    }
                    305:                    else if (pref->assoc == LEFT)
                    306:                    {
                    307:                        pref->suppressed = 2;
                    308:                        pref = p;
                    309:                    }
                    310:                    else if (pref->assoc == RIGHT)
                    311:                    {
                    312:                        p->suppressed = 2;
                    313:                    }
                    314:                    else
                    315:                    {
                    316:                        pref->suppressed = 2;
                    317:                        p->suppressed = 2;
                    318:                    }
                    319:                }
                    320:                else
                    321:                {
                    322:                    SRcount++;
                    323:                    p->suppressed = 1;
                    324:                }
                    325:            }
                    326:            else
                    327:            {
                    328:                RRcount++;
                    329:                p->suppressed = 1;
                    330:            }
                    331:        }
                    332:        SRtotal += SRcount;
                    333:        RRtotal += RRcount;
                    334:        SRconflicts[i] = SRcount;
                    335:        RRconflicts[i] = RRcount;
                    336:     }
                    337: }
                    338:
                    339:
1.6       pvalchev  340: void
1.1       deraadt   341: total_conflicts()
                    342: {
1.2       etheisen  343:     /* Warn if s/r != expect or if any r/r */
                    344:     if ((SRtotal != SRexpect) || RRtotal)
                    345:     {
                    346:         if (SRtotal == 1)
1.5       millert   347:             fprintf(stderr, "%s: 1 shift/reduce conflict\n", __progname);
1.2       etheisen  348:         else if (SRtotal > 1)
1.5       millert   349:             fprintf(stderr, "%s: %d shift/reduce conflicts\n", __progname,
1.2       etheisen  350:                     SRtotal);
                    351:     }
1.1       deraadt   352:
                    353:     if (RRtotal == 1)
1.5       millert   354:         fprintf(stderr, "%s: 1 reduce/reduce conflict\n", __progname);
1.1       deraadt   355:     else if (RRtotal > 1)
1.5       millert   356:        fprintf(stderr, "%s: %d reduce/reduce conflicts\n", __progname,
1.2       etheisen  357:                 RRtotal);
1.1       deraadt   358: }
                    359:
                    360:
                    361: int
                    362: sole_reduction(stateno)
                    363: int stateno;
                    364: {
1.7     ! mpech     365:     int count, ruleno;
        !           366:     action *p;
1.1       deraadt   367:
                    368:     count = 0;
                    369:     ruleno = 0;
                    370:     for (p = parser[stateno]; p; p = p->next)
                    371:     {
                    372:        if (p->action_code == SHIFT && p->suppressed == 0)
                    373:            return (0);
                    374:        else if (p->action_code == REDUCE && p->suppressed == 0)
                    375:        {
                    376:            if (ruleno > 0 && p->number != ruleno)
                    377:                return (0);
                    378:            if (p->symbol != 1)
                    379:                ++count;
                    380:            ruleno = p->number;
                    381:        }
                    382:     }
                    383:
                    384:     if (count == 0)
                    385:        return (0);
                    386:     return (ruleno);
                    387: }
                    388:
                    389:
1.6       pvalchev  390: void
1.1       deraadt   391: defreds()
                    392: {
1.7     ! mpech     393:     int i;
1.1       deraadt   394:
                    395:     defred = NEW2(nstates, short);
                    396:     for (i = 0; i < nstates; i++)
                    397:        defred[i] = sole_reduction(i);
                    398: }
                    399:
1.6       pvalchev  400: void
1.1       deraadt   401: free_action_row(p)
1.7     ! mpech     402: action *p;
1.1       deraadt   403: {
1.7     ! mpech     404:   action *q;
1.1       deraadt   405:
                    406:   while (p)
                    407:     {
                    408:       q = p->next;
                    409:       FREE(p);
                    410:       p = q;
                    411:     }
                    412: }
                    413:
1.6       pvalchev  414: void
1.1       deraadt   415: free_parser()
                    416: {
1.7     ! mpech     417:   int i;
1.1       deraadt   418:
                    419:   for (i = 0; i < nstates; i++)
                    420:     free_action_row(parser[i]);
                    421:
                    422:   FREE(parser);
                    423: }