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

Annotation of src/usr.bin/yacc/lr0.c, Revision 1.8

1.8     ! pvalchev    1: /*     $OpenBSD: lr0.c,v 1.7 2003/06/03 02:56:24 millert Exp $ */
1.2       deraadt     2: /*     $NetBSD: lr0.c,v 1.4 1996/03/19 03:21:35 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.7       millert    19:  * 3. Neither the name of the University nor the names of its contributors
1.2       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:  */
                     35:
1.1       deraadt    36: #ifndef lint
1.2       deraadt    37: #if 0
                     38: static char sccsid[] = "@(#)lr0.c      5.3 (Berkeley) 1/20/91";
                     39: #else
1.8     ! pvalchev   40: static char rcsid[] = "$OpenBSD: lr0.c,v 1.7 2003/06/03 02:56:24 millert Exp $";
1.2       deraadt    41: #endif
1.1       deraadt    42: #endif /* not lint */
                     43:
                     44: #include "defs.h"
                     45:
                     46: extern short *itemset;
                     47: extern short *itemsetend;
                     48: extern unsigned *ruleset;
                     49:
                     50: int nstates;
                     51: core *first_state;
                     52: shifts *first_shift;
                     53: reductions *first_reduction;
                     54:
1.6       millert    55: int get_state(int);
                     56: core *new_state(int);
1.4       pvalchev   57:
1.6       millert    58: void allocate_itemsets(void);
                     59: void allocate_storage(void);
                     60: void append_states(void);
                     61: void free_storage(void);
                     62: void generate_states(void);
                     63: void initialize_states(void);
                     64: void new_itemsets(void);
                     65: void show_cores(void);
                     66: void show_ritems(void);
                     67: void show_rrhs(void);
                     68: void show_shifts(void);
                     69: void save_shifts(void);
                     70: void save_reductions(void);
                     71: void set_derives(void);
                     72: void print_derives(void);
                     73: void set_nullable(void);
                     74: void free_derives(void);
                     75: void free_nullable(void);
1.1       deraadt    76:
                     77: static core **state_set;
                     78: static core *this_state;
                     79: static core *last_state;
                     80: static shifts *last_shift;
                     81: static reductions *last_reduction;
                     82:
                     83: static int nshifts;
                     84: static short *shift_symbol;
                     85:
                     86: static short *redset;
                     87: static short *shiftset;
                     88:
                     89: static short **kernel_base;
                     90: static short **kernel_end;
                     91: static short *kernel_items;
                     92:
1.4       pvalchev   93: void
1.8     ! pvalchev   94: allocate_itemsets(void)
1.1       deraadt    95: {
1.5       mpech      96:     short *itemp;
                     97:     short *item_end;
                     98:     int symbol;
                     99:     int i;
                    100:     int count;
                    101:     int max;
                    102:     short *symbol_count;
1.1       deraadt   103:
                    104:     count = 0;
                    105:     symbol_count = NEW2(nsyms, short);
                    106:
                    107:     item_end = ritem + nitems;
                    108:     for (itemp = ritem; itemp < item_end; itemp++)
                    109:     {
                    110:        symbol = *itemp;
                    111:        if (symbol >= 0)
                    112:        {
                    113:            count++;
                    114:            symbol_count[symbol]++;
                    115:        }
                    116:     }
                    117:
                    118:     kernel_base = NEW2(nsyms, short *);
                    119:     kernel_items = NEW2(count, short);
                    120:
                    121:     count = 0;
                    122:     max = 0;
                    123:     for (i = 0; i < nsyms; i++)
                    124:     {
                    125:        kernel_base[i] = kernel_items + count;
                    126:        count += symbol_count[i];
                    127:        if (max < symbol_count[i])
                    128:            max = symbol_count[i];
                    129:     }
                    130:
                    131:     shift_symbol = symbol_count;
                    132:     kernel_end = NEW2(nsyms, short *);
                    133: }
                    134:
1.4       pvalchev  135: void
1.8     ! pvalchev  136: allocate_storage(void)
1.1       deraadt   137: {
                    138:     allocate_itemsets();
                    139:     shiftset = NEW2(nsyms, short);
                    140:     redset = NEW2(nrules + 1, short);
                    141:     state_set = NEW2(nitems, core *);
                    142: }
                    143:
1.4       pvalchev  144: void
1.8     ! pvalchev  145: append_states(void)
1.1       deraadt   146: {
1.5       mpech     147:     int i;
                    148:     int j;
                    149:     int symbol;
1.1       deraadt   150:
                    151: #ifdef TRACE
                    152:     fprintf(stderr, "Entering append_states()\n");
                    153: #endif
                    154:     for (i = 1; i < nshifts; i++)
                    155:     {
                    156:        symbol = shift_symbol[i];
                    157:        j = i;
                    158:        while (j > 0 && shift_symbol[j - 1] > symbol)
                    159:        {
                    160:            shift_symbol[j] = shift_symbol[j - 1];
                    161:            j--;
                    162:        }
                    163:        shift_symbol[j] = symbol;
                    164:     }
                    165:
                    166:     for (i = 0; i < nshifts; i++)
                    167:     {
                    168:        symbol = shift_symbol[i];
                    169:        shiftset[i] = get_state(symbol);
                    170:     }
                    171: }
                    172:
1.4       pvalchev  173: void
1.8     ! pvalchev  174: free_storage(void)
1.1       deraadt   175: {
                    176:     FREE(shift_symbol);
                    177:     FREE(redset);
                    178:     FREE(shiftset);
                    179:     FREE(kernel_base);
                    180:     FREE(kernel_end);
                    181:     FREE(kernel_items);
                    182:     FREE(state_set);
                    183: }
                    184:
                    185:
1.4       pvalchev  186: void
1.8     ! pvalchev  187: generate_states(void)
1.1       deraadt   188: {
                    189:     allocate_storage();
                    190:     itemset = NEW2(nitems, short);
                    191:     ruleset = NEW2(WORDSIZE(nrules), unsigned);
                    192:     set_first_derives();
                    193:     initialize_states();
                    194:
                    195:     while (this_state)
                    196:     {
                    197:        closure(this_state->items, this_state->nitems);
                    198:        save_reductions();
                    199:        new_itemsets();
                    200:        append_states();
                    201:
                    202:        if (nshifts > 0)
                    203:            save_shifts();
                    204:
                    205:        this_state = this_state->next;
                    206:     }
                    207:
                    208:     finalize_closure();
                    209:     free_storage();
                    210: }
                    211:
                    212:
                    213:
                    214: int
1.8     ! pvalchev  215: get_state(int symbol)
1.1       deraadt   216: {
1.5       mpech     217:     int key;
                    218:     short *isp1;
                    219:     short *isp2;
                    220:     short *iend;
                    221:     core *sp;
                    222:     int found;
                    223:     int n;
1.1       deraadt   224:
                    225: #ifdef TRACE
                    226:     fprintf(stderr, "Entering get_state(%d)\n", symbol);
                    227: #endif
                    228:
                    229:     isp1 = kernel_base[symbol];
                    230:     iend = kernel_end[symbol];
                    231:     n = iend - isp1;
                    232:
                    233:     key = *isp1;
                    234:     assert(0 <= key && key < nitems);
                    235:     sp = state_set[key];
                    236:     if (sp)
                    237:     {
                    238:        found = 0;
                    239:        while (!found)
                    240:        {
                    241:            if (sp->nitems == n)
                    242:            {
                    243:                found = 1;
                    244:                isp1 = kernel_base[symbol];
                    245:                isp2 = sp->items;
                    246:
                    247:                while (found && isp1 < iend)
                    248:                {
                    249:                    if (*isp1++ != *isp2++)
                    250:                        found = 0;
                    251:                }
                    252:            }
                    253:
                    254:            if (!found)
                    255:            {
                    256:                if (sp->link)
                    257:                {
                    258:                    sp = sp->link;
                    259:                }
                    260:                else
                    261:                {
                    262:                    sp = sp->link = new_state(symbol);
                    263:                    found = 1;
                    264:                }
                    265:            }
                    266:        }
                    267:     }
                    268:     else
                    269:     {
                    270:        state_set[key] = sp = new_state(symbol);
                    271:     }
                    272:
                    273:     return (sp->number);
                    274: }
                    275:
                    276:
1.4       pvalchev  277: void
1.8     ! pvalchev  278: initialize_states(void)
1.1       deraadt   279: {
1.5       mpech     280:     int i;
                    281:     short *start_derives;
                    282:     core *p;
1.1       deraadt   283:
                    284:     start_derives = derives[start_symbol];
                    285:     for (i = 0; start_derives[i] >= 0; ++i)
                    286:        continue;
                    287:
                    288:     p = (core *) MALLOC(sizeof(core) + i*sizeof(short));
                    289:     if (p == 0) no_space();
                    290:
                    291:     p->next = 0;
                    292:     p->link = 0;
                    293:     p->number = 0;
                    294:     p->accessing_symbol = 0;
                    295:     p->nitems = i;
                    296:
                    297:     for (i = 0;  start_derives[i] >= 0; ++i)
                    298:        p->items[i] = rrhs[start_derives[i]];
                    299:
                    300:     first_state = last_state = this_state = p;
                    301:     nstates = 1;
                    302: }
                    303:
1.4       pvalchev  304: void
1.8     ! pvalchev  305: new_itemsets(void)
1.1       deraadt   306: {
1.5       mpech     307:     int i;
                    308:     int shiftcount;
                    309:     short *isp;
                    310:     short *ksp;
                    311:     int symbol;
1.1       deraadt   312:
                    313:     for (i = 0; i < nsyms; i++)
                    314:        kernel_end[i] = 0;
                    315:
                    316:     shiftcount = 0;
                    317:     isp = itemset;
                    318:     while (isp < itemsetend)
                    319:     {
                    320:        i = *isp++;
                    321:        symbol = ritem[i];
                    322:        if (symbol > 0)
                    323:        {
                    324:            ksp = kernel_end[symbol];
                    325:            if (!ksp)
                    326:            {
                    327:                shift_symbol[shiftcount++] = symbol;
                    328:                ksp = kernel_base[symbol];
                    329:            }
                    330:
                    331:            *ksp++ = i + 1;
                    332:            kernel_end[symbol] = ksp;
                    333:        }
                    334:     }
                    335:
                    336:     nshifts = shiftcount;
                    337: }
                    338:
                    339:
                    340:
                    341: core *
1.8     ! pvalchev  342: new_state(int symbol)
1.1       deraadt   343: {
1.5       mpech     344:     int n;
                    345:     core *p;
                    346:     short *isp1;
                    347:     short *isp2;
                    348:     short *iend;
1.1       deraadt   349:
                    350: #ifdef TRACE
                    351:     fprintf(stderr, "Entering new_state(%d)\n", symbol);
                    352: #endif
                    353:
                    354:     if (nstates >= MAXSHORT)
                    355:        fatal("too many states");
                    356:
                    357:     isp1 = kernel_base[symbol];
                    358:     iend = kernel_end[symbol];
                    359:     n = iend - isp1;
                    360:
                    361:     p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short)));
                    362:     p->accessing_symbol = symbol;
                    363:     p->number = nstates;
                    364:     p->nitems = n;
                    365:
                    366:     isp2 = p->items;
                    367:     while (isp1 < iend)
                    368:        *isp2++ = *isp1++;
                    369:
                    370:     last_state->next = p;
                    371:     last_state = p;
                    372:
                    373:     nstates++;
                    374:
                    375:     return (p);
                    376: }
                    377:
                    378:
                    379: /* show_cores is used for debugging */
                    380:
1.4       pvalchev  381: void
1.8     ! pvalchev  382: show_cores(void)
1.1       deraadt   383: {
                    384:     core *p;
                    385:     int i, j, k, n;
                    386:     int itemno;
                    387:
                    388:     k = 0;
                    389:     for (p = first_state; p; ++k, p = p->next)
                    390:     {
                    391:        if (k) printf("\n");
                    392:        printf("state %d, number = %d, accessing symbol = %s\n",
                    393:                k, p->number, symbol_name[p->accessing_symbol]);
                    394:        n = p->nitems;
                    395:        for (i = 0; i < n; ++i)
                    396:        {
                    397:            itemno = p->items[i];
                    398:            printf("%4d  ", itemno);
                    399:            j = itemno;
                    400:            while (ritem[j] >= 0) ++j;
                    401:            printf("%s :", symbol_name[rlhs[-ritem[j]]]);
                    402:            j = rrhs[-ritem[j]];
                    403:            while (j < itemno)
                    404:                printf(" %s", symbol_name[ritem[j++]]);
                    405:            printf(" .");
                    406:            while (ritem[j] >= 0)
                    407:                printf(" %s", symbol_name[ritem[j++]]);
                    408:            printf("\n");
                    409:            fflush(stdout);
                    410:        }
                    411:     }
                    412: }
                    413:
                    414:
                    415: /* show_ritems is used for debugging */
                    416:
1.4       pvalchev  417: void
1.8     ! pvalchev  418: show_ritems(void)
1.1       deraadt   419: {
                    420:     int i;
                    421:
                    422:     for (i = 0; i < nitems; ++i)
                    423:        printf("ritem[%d] = %d\n", i, ritem[i]);
                    424: }
                    425:
                    426:
                    427: /* show_rrhs is used for debugging */
1.4       pvalchev  428:
                    429: void
1.8     ! pvalchev  430: show_rrhs(void)
1.1       deraadt   431: {
                    432:     int i;
                    433:
                    434:     for (i = 0; i < nrules; ++i)
                    435:        printf("rrhs[%d] = %d\n", i, rrhs[i]);
                    436: }
                    437:
                    438:
                    439: /* show_shifts is used for debugging */
                    440:
1.4       pvalchev  441: void
1.8     ! pvalchev  442: show_shifts(void)
1.1       deraadt   443: {
                    444:     shifts *p;
                    445:     int i, j, k;
                    446:
                    447:     k = 0;
                    448:     for (p = first_shift; p; ++k, p = p->next)
                    449:     {
                    450:        if (k) printf("\n");
                    451:        printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
                    452:                p->nshifts);
                    453:        j = p->nshifts;
                    454:        for (i = 0; i < j; ++i)
                    455:            printf("\t%d\n", p->shift[i]);
                    456:     }
                    457: }
                    458:
1.4       pvalchev  459: void
1.8     ! pvalchev  460: save_shifts(void)
1.1       deraadt   461: {
1.5       mpech     462:     shifts *p;
                    463:     short *sp1;
                    464:     short *sp2;
                    465:     short *send;
1.1       deraadt   466:
                    467:     p = (shifts *) allocate((unsigned) (sizeof(shifts) +
                    468:                        (nshifts - 1) * sizeof(short)));
                    469:
                    470:     p->number = this_state->number;
                    471:     p->nshifts = nshifts;
                    472:
                    473:     sp1 = shiftset;
                    474:     sp2 = p->shift;
                    475:     send = shiftset + nshifts;
                    476:
                    477:     while (sp1 < send)
                    478:        *sp2++ = *sp1++;
                    479:
                    480:     if (last_shift)
                    481:     {
                    482:        last_shift->next = p;
                    483:        last_shift = p;
                    484:     }
                    485:     else
                    486:     {
                    487:        first_shift = p;
                    488:        last_shift = p;
                    489:     }
                    490: }
                    491:
                    492:
1.4       pvalchev  493: void
1.8     ! pvalchev  494: save_reductions(void)
1.1       deraadt   495: {
1.5       mpech     496:     short *isp;
                    497:     short *rp1;
                    498:     short *rp2;
                    499:     int item;
                    500:     int count;
                    501:     reductions *p;
                    502:     short *rend;
1.1       deraadt   503:
                    504:     count = 0;
                    505:     for (isp = itemset; isp < itemsetend; isp++)
                    506:     {
                    507:        item = ritem[*isp];
                    508:        if (item < 0)
                    509:        {
                    510:            redset[count++] = -item;
                    511:        }
                    512:     }
                    513:
                    514:     if (count)
                    515:     {
                    516:        p = (reductions *) allocate((unsigned) (sizeof(reductions) +
                    517:                                        (count - 1) * sizeof(short)));
                    518:
                    519:        p->number = this_state->number;
                    520:        p->nreds = count;
                    521:
                    522:        rp1 = redset;
                    523:        rp2 = p->rules;
                    524:        rend = rp1 + count;
                    525:
                    526:        while (rp1 < rend)
                    527:            *rp2++ = *rp1++;
                    528:
                    529:        if (last_reduction)
                    530:        {
                    531:            last_reduction->next = p;
                    532:            last_reduction = p;
                    533:        }
                    534:        else
                    535:        {
                    536:            first_reduction = p;
                    537:            last_reduction = p;
                    538:        }
                    539:     }
                    540: }
                    541:
1.4       pvalchev  542: void
1.8     ! pvalchev  543: set_derives(void)
1.1       deraadt   544: {
1.5       mpech     545:     int i, k;
                    546:     int lhs;
                    547:     short *rules;
1.1       deraadt   548:
                    549:     derives = NEW2(nsyms, short *);
                    550:     rules = NEW2(nvars + nrules, short);
                    551:
                    552:     k = 0;
                    553:     for (lhs = start_symbol; lhs < nsyms; lhs++)
                    554:     {
                    555:        derives[lhs] = rules + k;
                    556:        for (i = 0; i < nrules; i++)
                    557:        {
                    558:            if (rlhs[i] == lhs)
                    559:            {
                    560:                rules[k] = i;
                    561:                k++;
                    562:            }
                    563:        }
                    564:        rules[k] = -1;
                    565:        k++;
                    566:     }
                    567:
                    568: #ifdef DEBUG
                    569:     print_derives();
                    570: #endif
                    571: }
                    572:
1.4       pvalchev  573: void
1.8     ! pvalchev  574: free_derives(void)
1.1       deraadt   575: {
                    576:     FREE(derives[start_symbol]);
                    577:     FREE(derives);
                    578: }
                    579:
                    580: #ifdef DEBUG
1.4       pvalchev  581: void
1.8     ! pvalchev  582: print_derives(void)
1.1       deraadt   583: {
1.5       mpech     584:     int i;
                    585:     short *sp;
1.1       deraadt   586:
                    587:     printf("\nDERIVES\n\n");
                    588:
                    589:     for (i = start_symbol; i < nsyms; i++)
                    590:     {
                    591:        printf("%s derives ", symbol_name[i]);
                    592:        for (sp = derives[i]; *sp >= 0; sp++)
                    593:        {
                    594:            printf("  %d", *sp);
                    595:        }
                    596:        putchar('\n');
                    597:     }
                    598:
                    599:     putchar('\n');
                    600: }
                    601: #endif
                    602:
1.4       pvalchev  603: void
1.8     ! pvalchev  604: set_nullable(void)
1.1       deraadt   605: {
1.5       mpech     606:     int i, j;
                    607:     int empty;
1.1       deraadt   608:     int done;
                    609:
                    610:     nullable = MALLOC(nsyms);
                    611:     if (nullable == 0) no_space();
                    612:
                    613:     for (i = 0; i < nsyms; ++i)
                    614:        nullable[i] = 0;
                    615:
                    616:     done = 0;
                    617:     while (!done)
                    618:     {
                    619:        done = 1;
                    620:        for (i = 1; i < nitems; i++)
                    621:        {
                    622:            empty = 1;
                    623:            while ((j = ritem[i]) >= 0)
                    624:            {
                    625:                if (!nullable[j])
                    626:                    empty = 0;
                    627:                ++i;
                    628:            }
                    629:            if (empty)
                    630:            {
                    631:                j = rlhs[-j];
                    632:                if (!nullable[j])
                    633:                {
                    634:                    nullable[j] = 1;
                    635:                    done = 0;
                    636:                }
                    637:            }
                    638:        }
                    639:     }
                    640:
                    641: #ifdef DEBUG
                    642:     for (i = 0; i < nsyms; i++)
                    643:     {
                    644:        if (nullable[i])
                    645:            printf("%s is nullable\n", symbol_name[i]);
                    646:        else
                    647:            printf("%s is not nullable\n", symbol_name[i]);
                    648:     }
                    649: #endif
                    650: }
                    651:
1.4       pvalchev  652: void
1.8     ! pvalchev  653: free_nullable(void)
1.1       deraadt   654: {
                    655:     FREE(nullable);
                    656: }
                    657:
1.4       pvalchev  658: void
1.8     ! pvalchev  659: lr0(void)
1.1       deraadt   660: {
                    661:     set_derives();
                    662:     set_nullable();
                    663:     generate_states();
                    664: }