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

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