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

Annotation of src/usr.bin/yacc/lalr.c, Revision 1.2

1.2     ! deraadt     1: /*     $NetBSD: lalr.c,v 1.4 1996/03/19 03:21:33 jtc Exp $     */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 1989 The Regents of the University of California.
        !             5:  * All rights reserved.
        !             6:  *
        !             7:  * This code is derived from software contributed to Berkeley by
        !             8:  * Robert Paul Corbett.
        !             9:  *
        !            10:  * Redistribution and use in source and binary forms, with or without
        !            11:  * modification, are permitted provided that the following conditions
        !            12:  * are met:
        !            13:  * 1. Redistributions of source code must retain the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer.
        !            15:  * 2. Redistributions in binary form must reproduce the above copyright
        !            16:  *    notice, this list of conditions and the following disclaimer in the
        !            17:  *    documentation and/or other materials provided with the distribution.
        !            18:  * 3. All advertising materials mentioning features or use of this software
        !            19:  *    must display the following acknowledgement:
        !            20:  *     This product includes software developed by the University of
        !            21:  *     California, Berkeley and its contributors.
        !            22:  * 4. Neither the name of the University nor the names of its contributors
        !            23:  *    may be used to endorse or promote products derived from this software
        !            24:  *    without specific prior written permission.
        !            25:  *
        !            26:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            28:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            29:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            30:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            31:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            32:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            33:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            34:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            35:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            36:  * SUCH DAMAGE.
        !            37:  */
        !            38:
1.1       deraadt    39: #ifndef lint
1.2     ! deraadt    40: #if 0
        !            41: static char sccsid[] = "@(#)lalr.c     5.3 (Berkeley) 6/1/90";
        !            42: #else
        !            43: static char rcsid[] = "$NetBSD: lalr.c,v 1.4 1996/03/19 03:21:33 jtc Exp $";
        !            44: #endif
1.1       deraadt    45: #endif /* not lint */
                     46:
                     47: #include "defs.h"
                     48:
                     49: typedef
                     50:   struct shorts
                     51:     {
                     52:       struct shorts *next;
                     53:       short value;
                     54:     }
                     55:   shorts;
                     56:
                     57: int tokensetsize;
                     58: short *lookaheads;
                     59: short *LAruleno;
                     60: unsigned *LA;
                     61: short *accessing_symbol;
                     62: core **state_table;
                     63: shifts **shift_table;
                     64: reductions **reduction_table;
                     65: short *goto_map;
                     66: short *from_state;
                     67: short *to_state;
                     68:
                     69: short **transpose();
                     70:
                     71: static int infinity;
                     72: static int maxrhs;
                     73: static int ngotos;
                     74: static unsigned *F;
                     75: static short **includes;
                     76: static shorts **lookback;
                     77: static short **R;
                     78: static short *INDEX;
                     79: static short *VERTICES;
                     80: static int top;
                     81:
                     82:
                     83: lalr()
                     84: {
                     85:     tokensetsize = WORDSIZE(ntokens);
                     86:
                     87:     set_state_table();
                     88:     set_accessing_symbol();
                     89:     set_shift_table();
                     90:     set_reduction_table();
                     91:     set_maxrhs();
                     92:     initialize_LA();
                     93:     set_goto_map();
                     94:     initialize_F();
                     95:     build_relations();
                     96:     compute_FOLLOWS();
                     97:     compute_lookaheads();
                     98: }
                     99:
                    100:
                    101:
                    102: set_state_table()
                    103: {
                    104:     register core *sp;
                    105:
                    106:     state_table = NEW2(nstates, core *);
                    107:     for (sp = first_state; sp; sp = sp->next)
                    108:        state_table[sp->number] = sp;
                    109: }
                    110:
                    111:
                    112:
                    113: set_accessing_symbol()
                    114: {
                    115:     register core *sp;
                    116:
                    117:     accessing_symbol = NEW2(nstates, short);
                    118:     for (sp = first_state; sp; sp = sp->next)
                    119:        accessing_symbol[sp->number] = sp->accessing_symbol;
                    120: }
                    121:
                    122:
                    123:
                    124: set_shift_table()
                    125: {
                    126:     register shifts *sp;
                    127:
                    128:     shift_table = NEW2(nstates, shifts *);
                    129:     for (sp = first_shift; sp; sp = sp->next)
                    130:        shift_table[sp->number] = sp;
                    131: }
                    132:
                    133:
                    134:
                    135: set_reduction_table()
                    136: {
                    137:     register reductions *rp;
                    138:
                    139:     reduction_table = NEW2(nstates, reductions *);
                    140:     for (rp = first_reduction; rp; rp = rp->next)
                    141:        reduction_table[rp->number] = rp;
                    142: }
                    143:
                    144:
                    145:
                    146: set_maxrhs()
                    147: {
                    148:   register short *itemp;
                    149:   register short *item_end;
                    150:   register int length;
                    151:   register int max;
                    152:
                    153:   length = 0;
                    154:   max = 0;
                    155:   item_end = ritem + nitems;
                    156:   for (itemp = ritem; itemp < item_end; itemp++)
                    157:     {
                    158:       if (*itemp >= 0)
                    159:        {
                    160:          length++;
                    161:        }
                    162:       else
                    163:        {
                    164:          if (length > max) max = length;
                    165:          length = 0;
                    166:        }
                    167:     }
                    168:
                    169:   maxrhs = max;
                    170: }
                    171:
                    172:
                    173:
                    174: initialize_LA()
                    175: {
                    176:   register int i, j, k;
                    177:   register reductions *rp;
                    178:
                    179:   lookaheads = NEW2(nstates + 1, short);
                    180:
                    181:   k = 0;
                    182:   for (i = 0; i < nstates; i++)
                    183:     {
                    184:       lookaheads[i] = k;
                    185:       rp = reduction_table[i];
                    186:       if (rp)
                    187:        k += rp->nreds;
                    188:     }
                    189:   lookaheads[nstates] = k;
                    190:
                    191:   LA = NEW2(k * tokensetsize, unsigned);
                    192:   LAruleno = NEW2(k, short);
                    193:   lookback = NEW2(k, shorts *);
                    194:
                    195:   k = 0;
                    196:   for (i = 0; i < nstates; i++)
                    197:     {
                    198:       rp = reduction_table[i];
                    199:       if (rp)
                    200:        {
                    201:          for (j = 0; j < rp->nreds; j++)
                    202:            {
                    203:              LAruleno[k] = rp->rules[j];
                    204:              k++;
                    205:            }
                    206:        }
                    207:     }
                    208: }
                    209:
                    210:
                    211: set_goto_map()
                    212: {
                    213:   register shifts *sp;
                    214:   register int i;
                    215:   register int symbol;
                    216:   register int k;
                    217:   register short *temp_map;
                    218:   register int state2;
                    219:   register int state1;
                    220:
                    221:   goto_map = NEW2(nvars + 1, short) - ntokens;
                    222:   temp_map = NEW2(nvars + 1, short) - ntokens;
                    223:
                    224:   ngotos = 0;
                    225:   for (sp = first_shift; sp; sp = sp->next)
                    226:     {
                    227:       for (i = sp->nshifts - 1; i >= 0; i--)
                    228:        {
                    229:          symbol = accessing_symbol[sp->shift[i]];
                    230:
                    231:          if (ISTOKEN(symbol)) break;
                    232:
                    233:          if (ngotos == MAXSHORT)
                    234:            fatal("too many gotos");
                    235:
                    236:          ngotos++;
                    237:          goto_map[symbol]++;
                    238:         }
                    239:     }
                    240:
                    241:   k = 0;
                    242:   for (i = ntokens; i < nsyms; i++)
                    243:     {
                    244:       temp_map[i] = k;
                    245:       k += goto_map[i];
                    246:     }
                    247:
                    248:   for (i = ntokens; i < nsyms; i++)
                    249:     goto_map[i] = temp_map[i];
                    250:
                    251:   goto_map[nsyms] = ngotos;
                    252:   temp_map[nsyms] = ngotos;
                    253:
                    254:   from_state = NEW2(ngotos, short);
                    255:   to_state = NEW2(ngotos, short);
                    256:
                    257:   for (sp = first_shift; sp; sp = sp->next)
                    258:     {
                    259:       state1 = sp->number;
                    260:       for (i = sp->nshifts - 1; i >= 0; i--)
                    261:        {
                    262:          state2 = sp->shift[i];
                    263:          symbol = accessing_symbol[state2];
                    264:
                    265:          if (ISTOKEN(symbol)) break;
                    266:
                    267:          k = temp_map[symbol]++;
                    268:          from_state[k] = state1;
                    269:          to_state[k] = state2;
                    270:        }
                    271:     }
                    272:
                    273:   FREE(temp_map + ntokens);
                    274: }
                    275:
                    276:
                    277:
                    278: /*  Map_goto maps a state/symbol pair into its numeric representation. */
                    279:
                    280: int
                    281: map_goto(state, symbol)
                    282: int state;
                    283: int symbol;
                    284: {
                    285:     register int high;
                    286:     register int low;
                    287:     register int middle;
                    288:     register int s;
                    289:
                    290:     low = goto_map[symbol];
                    291:     high = goto_map[symbol + 1];
                    292:
                    293:     for (;;)
                    294:     {
                    295:        assert(low <= high);
                    296:        middle = (low + high) >> 1;
                    297:        s = from_state[middle];
                    298:        if (s == state)
                    299:            return (middle);
                    300:        else if (s < state)
                    301:            low = middle + 1;
                    302:        else
                    303:            high = middle - 1;
                    304:     }
                    305: }
                    306:
                    307:
                    308:
                    309: initialize_F()
                    310: {
                    311:   register int i;
                    312:   register int j;
                    313:   register int k;
                    314:   register shifts *sp;
                    315:   register short *edge;
                    316:   register unsigned *rowp;
                    317:   register short *rp;
                    318:   register short **reads;
                    319:   register int nedges;
                    320:   register int stateno;
                    321:   register int symbol;
                    322:   register int nwords;
                    323:
                    324:   nwords = ngotos * tokensetsize;
                    325:   F = NEW2(nwords, unsigned);
                    326:
                    327:   reads = NEW2(ngotos, short *);
                    328:   edge = NEW2(ngotos + 1, short);
                    329:   nedges = 0;
                    330:
                    331:   rowp = F;
                    332:   for (i = 0; i < ngotos; i++)
                    333:     {
                    334:       stateno = to_state[i];
                    335:       sp = shift_table[stateno];
                    336:
                    337:       if (sp)
                    338:        {
                    339:          k = sp->nshifts;
                    340:
                    341:          for (j = 0; j < k; j++)
                    342:            {
                    343:              symbol = accessing_symbol[sp->shift[j]];
                    344:              if (ISVAR(symbol))
                    345:                break;
                    346:              SETBIT(rowp, symbol);
                    347:            }
                    348:
                    349:          for (; j < k; j++)
                    350:            {
                    351:              symbol = accessing_symbol[sp->shift[j]];
                    352:              if (nullable[symbol])
                    353:                edge[nedges++] = map_goto(stateno, symbol);
                    354:            }
                    355:
                    356:          if (nedges)
                    357:            {
                    358:              reads[i] = rp = NEW2(nedges + 1, short);
                    359:
                    360:              for (j = 0; j < nedges; j++)
                    361:                rp[j] = edge[j];
                    362:
                    363:              rp[nedges] = -1;
                    364:              nedges = 0;
                    365:            }
                    366:        }
                    367:
                    368:       rowp += tokensetsize;
                    369:     }
                    370:
                    371:   SETBIT(F, 0);
                    372:   digraph(reads);
                    373:
                    374:   for (i = 0; i < ngotos; i++)
                    375:     {
                    376:       if (reads[i])
                    377:        FREE(reads[i]);
                    378:     }
                    379:
                    380:   FREE(reads);
                    381:   FREE(edge);
                    382: }
                    383:
                    384:
                    385:
                    386: build_relations()
                    387: {
                    388:   register int i;
                    389:   register int j;
                    390:   register int k;
                    391:   register short *rulep;
                    392:   register short *rp;
                    393:   register shifts *sp;
                    394:   register int length;
                    395:   register int nedges;
                    396:   register int done;
                    397:   register int state1;
                    398:   register int stateno;
                    399:   register int symbol1;
                    400:   register int symbol2;
                    401:   register short *shortp;
                    402:   register short *edge;
                    403:   register short *states;
                    404:   register short **new_includes;
                    405:
                    406:   includes = NEW2(ngotos, short *);
                    407:   edge = NEW2(ngotos + 1, short);
                    408:   states = NEW2(maxrhs + 1, short);
                    409:
                    410:   for (i = 0; i < ngotos; i++)
                    411:     {
                    412:       nedges = 0;
                    413:       state1 = from_state[i];
                    414:       symbol1 = accessing_symbol[to_state[i]];
                    415:
                    416:       for (rulep = derives[symbol1]; *rulep >= 0; rulep++)
                    417:        {
                    418:          length = 1;
                    419:          states[0] = state1;
                    420:          stateno = state1;
                    421:
                    422:          for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++)
                    423:            {
                    424:              symbol2 = *rp;
                    425:              sp = shift_table[stateno];
                    426:              k = sp->nshifts;
                    427:
                    428:              for (j = 0; j < k; j++)
                    429:                {
                    430:                  stateno = sp->shift[j];
                    431:                  if (accessing_symbol[stateno] == symbol2) break;
                    432:                }
                    433:
                    434:              states[length++] = stateno;
                    435:            }
                    436:
                    437:          add_lookback_edge(stateno, *rulep, i);
                    438:
                    439:          length--;
                    440:          done = 0;
                    441:          while (!done)
                    442:            {
                    443:              done = 1;
                    444:              rp--;
                    445:              if (ISVAR(*rp))
                    446:                {
                    447:                  stateno = states[--length];
                    448:                  edge[nedges++] = map_goto(stateno, *rp);
                    449:                  if (nullable[*rp] && length > 0) done = 0;
                    450:                }
                    451:            }
                    452:        }
                    453:
                    454:       if (nedges)
                    455:        {
                    456:          includes[i] = shortp = NEW2(nedges + 1, short);
                    457:          for (j = 0; j < nedges; j++)
                    458:            shortp[j] = edge[j];
                    459:          shortp[nedges] = -1;
                    460:        }
                    461:     }
                    462:
                    463:   new_includes = transpose(includes, ngotos);
                    464:
                    465:   for (i = 0; i < ngotos; i++)
                    466:     if (includes[i])
                    467:       FREE(includes[i]);
                    468:
                    469:   FREE(includes);
                    470:
                    471:   includes = new_includes;
                    472:
                    473:   FREE(edge);
                    474:   FREE(states);
                    475: }
                    476:
                    477:
                    478: add_lookback_edge(stateno, ruleno, gotono)
                    479: int stateno, ruleno, gotono;
                    480: {
                    481:     register int i, k;
                    482:     register int found;
                    483:     register shorts *sp;
                    484:
                    485:     i = lookaheads[stateno];
                    486:     k = lookaheads[stateno + 1];
                    487:     found = 0;
                    488:     while (!found && i < k)
                    489:     {
                    490:        if (LAruleno[i] == ruleno)
                    491:            found = 1;
                    492:        else
                    493:            ++i;
                    494:     }
                    495:     assert(found);
                    496:
                    497:     sp = NEW(shorts);
                    498:     sp->next = lookback[i];
                    499:     sp->value = gotono;
                    500:     lookback[i] = sp;
                    501: }
                    502:
                    503:
                    504:
                    505: short **
                    506: transpose(R, n)
                    507: short **R;
                    508: int n;
                    509: {
                    510:   register short **new_R;
                    511:   register short **temp_R;
                    512:   register short *nedges;
                    513:   register short *sp;
                    514:   register int i;
                    515:   register int k;
                    516:
                    517:   nedges = NEW2(n, short);
                    518:
                    519:   for (i = 0; i < n; i++)
                    520:     {
                    521:       sp = R[i];
                    522:       if (sp)
                    523:        {
                    524:          while (*sp >= 0)
                    525:            nedges[*sp++]++;
                    526:        }
                    527:     }
                    528:
                    529:   new_R = NEW2(n, short *);
                    530:   temp_R = NEW2(n, short *);
                    531:
                    532:   for (i = 0; i < n; i++)
                    533:     {
                    534:       k = nedges[i];
                    535:       if (k > 0)
                    536:        {
                    537:          sp = NEW2(k + 1, short);
                    538:          new_R[i] = sp;
                    539:          temp_R[i] = sp;
                    540:          sp[k] = -1;
                    541:        }
                    542:     }
                    543:
                    544:   FREE(nedges);
                    545:
                    546:   for (i = 0; i < n; i++)
                    547:     {
                    548:       sp = R[i];
                    549:       if (sp)
                    550:        {
                    551:          while (*sp >= 0)
                    552:            *temp_R[*sp++]++ = i;
                    553:        }
                    554:     }
                    555:
                    556:   FREE(temp_R);
                    557:
                    558:   return (new_R);
                    559: }
                    560:
                    561:
                    562:
                    563: compute_FOLLOWS()
                    564: {
                    565:   digraph(includes);
                    566: }
                    567:
                    568:
                    569: compute_lookaheads()
                    570: {
                    571:   register int i, n;
                    572:   register unsigned *fp1, *fp2, *fp3;
                    573:   register shorts *sp, *next;
                    574:   register unsigned *rowp;
                    575:
                    576:   rowp = LA;
                    577:   n = lookaheads[nstates];
                    578:   for (i = 0; i < n; i++)
                    579:     {
                    580:       fp3 = rowp + tokensetsize;
                    581:       for (sp = lookback[i]; sp; sp = sp->next)
                    582:        {
                    583:          fp1 = rowp;
                    584:          fp2 = F + tokensetsize * sp->value;
                    585:          while (fp1 < fp3)
                    586:            *fp1++ |= *fp2++;
                    587:        }
                    588:       rowp = fp3;
                    589:     }
                    590:
                    591:   for (i = 0; i < n; i++)
                    592:     for (sp = lookback[i]; sp; sp = next)
                    593:       {
                    594:         next = sp->next;
                    595:         FREE(sp);
                    596:       }
                    597:
                    598:   FREE(lookback);
                    599:   FREE(F);
                    600: }
                    601:
                    602:
                    603: digraph(relation)
                    604: short **relation;
                    605: {
                    606:   register int i;
                    607:
                    608:   infinity = ngotos + 2;
                    609:   INDEX = NEW2(ngotos + 1, short);
                    610:   VERTICES = NEW2(ngotos + 1, short);
                    611:   top = 0;
                    612:
                    613:   R = relation;
                    614:
                    615:   for (i = 0; i < ngotos; i++)
                    616:     INDEX[i] = 0;
                    617:
                    618:   for (i = 0; i < ngotos; i++)
                    619:     {
                    620:       if (INDEX[i] == 0 && R[i])
                    621:        traverse(i);
                    622:     }
                    623:
                    624:   FREE(INDEX);
                    625:   FREE(VERTICES);
                    626: }
                    627:
                    628:
                    629:
                    630: traverse(i)
                    631: register int i;
                    632: {
                    633:   register unsigned *fp1;
                    634:   register unsigned *fp2;
                    635:   register unsigned *fp3;
                    636:   register int j;
                    637:   register short *rp;
                    638:
                    639:   int height;
                    640:   unsigned *base;
                    641:
                    642:   VERTICES[++top] = i;
                    643:   INDEX[i] = height = top;
                    644:
                    645:   base = F + i * tokensetsize;
                    646:   fp3 = base + tokensetsize;
                    647:
                    648:   rp = R[i];
                    649:   if (rp)
                    650:     {
                    651:       while ((j = *rp++) >= 0)
                    652:        {
                    653:          if (INDEX[j] == 0)
                    654:            traverse(j);
                    655:
                    656:          if (INDEX[i] > INDEX[j])
                    657:            INDEX[i] = INDEX[j];
                    658:
                    659:          fp1 = base;
                    660:          fp2 = F + j * tokensetsize;
                    661:
                    662:          while (fp1 < fp3)
                    663:            *fp1++ |= *fp2++;
                    664:        }
                    665:     }
                    666:
                    667:   if (INDEX[i] == height)
                    668:     {
                    669:       for (;;)
                    670:        {
                    671:          j = VERTICES[top--];
                    672:          INDEX[j] = infinity;
                    673:
                    674:          if (i == j)
                    675:            break;
                    676:
                    677:          fp1 = base;
                    678:          fp2 = F + j * tokensetsize;
                    679:
                    680:          while (fp1 < fp3)
                    681:            *fp2++ = *fp1++;
                    682:        }
                    683:     }
                    684: }