Annotation of GNUtools/bison/LR0.c, revision 1.1.1.1

1.1       root        1: /* Generate the nondeterministic finite state machine for bison,
                      2:    Copyright (C) 1984, 1986, 1989 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of Bison, the GNU Compiler Compiler.
                      5: 
                      6: Bison is free software; you can redistribute it and/or modify
                      7: it under the terms of the GNU General Public License as published by
                      8: the Free Software Foundation; either version 2, or (at your option)
                      9: any later version.
                     10: 
                     11: Bison is distributed in the hope that it will be useful,
                     12: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: GNU General Public License for more details.
                     15: 
                     16: You should have received a copy of the GNU General Public License
                     17: along with Bison; see the file COPYING.  If not, write to
                     18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     19: 
                     20: 
                     21: /* See comments in state.h for the data structures that represent it.
                     22:    The entry point is generate_states.  */
                     23: 
                     24: #include <stdio.h>
                     25: #include "system.h"
                     26: #include "machine.h"
                     27: #include "new.h"
                     28: #include "gram.h"
                     29: #include "state.h"
                     30: 
                     31: 
                     32: extern char *nullable;
                     33: extern short *itemset;
                     34: extern short *itemsetend;
                     35: 
                     36: 
                     37: int nstates;
                     38: int final_state;
                     39: core *first_state;
                     40: shifts *first_shift;
                     41: reductions *first_reduction;
                     42: 
                     43: int get_state();
                     44: core *new_state();
                     45: 
                     46: void new_itemsets();
                     47: void append_states();
                     48: void initialize_states();
                     49: void save_shifts();
                     50: void save_reductions();
                     51: void augment_automaton();
                     52: void insert_start_shift();
                     53: extern void initialize_closure();
                     54: extern void closure();
                     55: extern void finalize_closure();
                     56: extern void toomany();
                     57: 
                     58: static core *this_state;
                     59: static core *last_state;
                     60: static shifts *last_shift;
                     61: static reductions *last_reduction;
                     62: 
                     63: static int nshifts;
                     64: static short *shift_symbol;
                     65: 
                     66: static short *redset;
                     67: static short *shiftset;
                     68: 
                     69: static short **kernel_base;
                     70: static short **kernel_end;
                     71: static short *kernel_items;
                     72: 
                     73: /* hash table for states, to recognize equivalent ones.  */
                     74: 
                     75: #define        STATE_TABLE_SIZE        1009
                     76: static core **state_table;
                     77: 
                     78: 
                     79: 
                     80: void
                     81: allocate_itemsets()
                     82: {
                     83:   register short *itemp;
                     84:   register int symbol;
                     85:   register int i;
                     86:   register int count;
                     87:   register short *symbol_count;
                     88: 
                     89:   count = 0;
                     90:   symbol_count = NEW2(nsyms, short);
                     91: 
                     92:   itemp = ritem;
                     93:   symbol = *itemp++;
                     94:   while (symbol)
                     95:     {
                     96:       if (symbol > 0)
                     97:        {
                     98:          count++;
                     99:          symbol_count[symbol]++;
                    100:        }
                    101:       symbol = *itemp++;
                    102:     }
                    103: 
                    104:   /* see comments before new_itemsets.  All the vectors of items
                    105:      live inside kernel_items.  The number of active items after
                    106:      some symbol cannot be more than the number of times that symbol
                    107:      appears as an item, which is symbol_count[symbol].
                    108:      We allocate that much space for each symbol.  */
                    109: 
                    110:   kernel_base = NEW2(nsyms, short *);
                    111:   kernel_items = NEW2(count, short);
                    112: 
                    113:   count = 0;
                    114:   for (i = 0; i < nsyms; i++)
                    115:     {
                    116:       kernel_base[i] = kernel_items + count;
                    117:       count += symbol_count[i];
                    118:     }
                    119: 
                    120:   shift_symbol = symbol_count;
                    121:   kernel_end = NEW2(nsyms, short *);
                    122: }
                    123: 
                    124: 
                    125: void
                    126: allocate_storage()
                    127: {
                    128:   allocate_itemsets();
                    129: 
                    130:   shiftset = NEW2(nsyms, short);
                    131:   redset = NEW2(nrules + 1, short);
                    132:   state_table = NEW2(STATE_TABLE_SIZE, core *);
                    133: }
                    134: 
                    135: 
                    136: void
                    137: free_storage()
                    138: {
                    139:   FREE(shift_symbol);
                    140:   FREE(redset);
                    141:   FREE(shiftset);
                    142:   FREE(kernel_base);
                    143:   FREE(kernel_end);
                    144:   FREE(kernel_items);
                    145:   FREE(state_table);
                    146: }
                    147: 
                    148: 
                    149: 
                    150: /* compute the nondeterministic finite state machine (see state.h for details)
                    151: from the grammar.  */
                    152: void
                    153: generate_states()
                    154: {
                    155:   allocate_storage();
                    156:   initialize_closure(nitems);
                    157:   initialize_states();
                    158: 
                    159:   while (this_state)
                    160:     {
                    161:       /* Set up ruleset and itemset for the transitions out of this state.
                    162:          ruleset gets a 1 bit for each rule that could reduce now.
                    163:         itemset gets a vector of all the items that could be accepted next.  */
                    164:       closure(this_state->items, this_state->nitems);
                    165:       /* record the reductions allowed out of this state */
                    166:       save_reductions();
                    167:       /* find the itemsets of the states that shifts can reach */
                    168:       new_itemsets();
                    169:       /* find or create the core structures for those states */
                    170:       append_states();
                    171: 
                    172:       /* create the shifts structures for the shifts to those states,
                    173:          now that the state numbers transitioning to are known */
                    174:       if (nshifts > 0)
                    175:         save_shifts();
                    176: 
                    177:       /* states are queued when they are created; process them all */
                    178:       this_state = this_state->next;
                    179:     }
                    180: 
                    181:   /* discard various storage */
                    182:   finalize_closure();
                    183:   free_storage();
                    184: 
                    185:   /* set up initial and final states as parser wants them */
                    186:   augment_automaton();
                    187: }
                    188: 
                    189: 
                    190: 
                    191: /* Find which symbols can be shifted in the current state,
                    192:    and for each one record which items would be active after that shift.
                    193:    Uses the contents of itemset.
                    194:    shift_symbol is set to a vector of the symbols that can be shifted.
                    195:    For each symbol in the grammar, kernel_base[symbol] points to
                    196:    a vector of item numbers activated if that symbol is shifted,
                    197:    and kernel_end[symbol] points after the end of that vector.  */
                    198: void
                    199: new_itemsets()
                    200: {
                    201:   register int i;
                    202:   register int shiftcount;
                    203:   register short *isp;
                    204:   register short *ksp;
                    205:   register int symbol;
                    206: 
                    207: #ifdef TRACE
                    208:   fprintf(stderr, "Entering new_itemsets\n");
                    209: #endif
                    210: 
                    211:   for (i = 0; i < nsyms; i++)
                    212:     kernel_end[i] = NULL;
                    213: 
                    214:   shiftcount = 0;
                    215: 
                    216:   isp = itemset;
                    217: 
                    218:   while (isp < itemsetend)
                    219:     {
                    220:       i = *isp++;
                    221:       symbol = ritem[i];
                    222:       if (symbol > 0)
                    223:        {
                    224:           ksp = kernel_end[symbol];
                    225: 
                    226:           if (!ksp)
                    227:            {
                    228:              shift_symbol[shiftcount++] = symbol;
                    229:              ksp = kernel_base[symbol];
                    230:            }
                    231: 
                    232:           *ksp++ = i + 1;
                    233:           kernel_end[symbol] = ksp;
                    234:        }
                    235:     }
                    236: 
                    237:   nshifts = shiftcount;
                    238: }
                    239: 
                    240: 
                    241: 
                    242: /* Use the information computed by new_itemsets to find the state numbers
                    243:    reached by each shift transition from the current state.
                    244: 
                    245:    shiftset is set up as a vector of state numbers of those states.  */
                    246: void
                    247: append_states()
                    248: {
                    249:   register int i;
                    250:   register int j;
                    251:   register int symbol;
                    252: 
                    253: #ifdef TRACE
                    254:   fprintf(stderr, "Entering append_states\n");
                    255: #endif
                    256: 
                    257:   /* first sort shift_symbol into increasing order */
                    258: 
                    259:   for (i = 1; i < nshifts; i++)
                    260:     {
                    261:       symbol = shift_symbol[i];
                    262:       j = i;
                    263:       while (j > 0 && shift_symbol[j - 1] > symbol)
                    264:        {
                    265:          shift_symbol[j] = shift_symbol[j - 1];
                    266:          j--;
                    267:        }
                    268:       shift_symbol[j] = symbol;
                    269:     }
                    270: 
                    271:   for (i = 0; i < nshifts; i++)
                    272:     {
                    273:       symbol = shift_symbol[i];
                    274:       shiftset[i] = get_state(symbol);
                    275:     }
                    276: }
                    277: 
                    278: 
                    279: 
                    280: /* find the state number for the state we would get to
                    281: (from the current state) by shifting symbol.
                    282: Create a new state if no equivalent one exists already.
                    283: Used by append_states  */
                    284: 
                    285: int
                    286: get_state(symbol)
                    287: int symbol;
                    288: {
                    289:   register int key;
                    290:   register short *isp1;
                    291:   register short *isp2;
                    292:   register short *iend;
                    293:   register core *sp;
                    294:   register int found;
                    295: 
                    296:   int n;
                    297: 
                    298: #ifdef TRACE
                    299:   fprintf(stderr, "Entering get_state, symbol = %d\n", symbol);
                    300: #endif
                    301: 
                    302:   isp1 = kernel_base[symbol];
                    303:   iend = kernel_end[symbol];
                    304:   n = iend - isp1;
                    305: 
                    306:   /* add up the target state's active item numbers to get a hash key */
                    307:   key = 0;
                    308:   while (isp1 < iend)
                    309:     key += *isp1++;
                    310: 
                    311:   key = key % STATE_TABLE_SIZE;
                    312: 
                    313:   sp = state_table[key];
                    314: 
                    315:   if (sp)
                    316:     {
                    317:       found = 0;
                    318:       while (!found)
                    319:        {
                    320:          if (sp->nitems == n)
                    321:            {
                    322:              found = 1;
                    323:              isp1 = kernel_base[symbol];
                    324:              isp2 = sp->items;
                    325: 
                    326:              while (found && isp1 < iend)
                    327:                {
                    328:                  if (*isp1++ != *isp2++)
                    329:                    found = 0;
                    330:                }
                    331:            }
                    332: 
                    333:          if (!found)
                    334:            {
                    335:              if (sp->link)
                    336:                {
                    337:                  sp = sp->link;
                    338:                }
                    339:              else   /* bucket exhausted and no match */
                    340:                {
                    341:                  sp = sp->link = new_state(symbol);
                    342:                  found = 1;
                    343:                }
                    344:            }
                    345:        }
                    346:     }
                    347:   else      /* bucket is empty */
                    348:     {
                    349:       state_table[key] = sp = new_state(symbol);
                    350:     }
                    351: 
                    352:   return (sp->number);
                    353: }
                    354: 
                    355: 
                    356: 
                    357: /* subroutine of get_state.  create a new state for those items, if necessary.  */
                    358: 
                    359: core *
                    360: new_state(symbol)
                    361: int symbol;
                    362: {
                    363:   register int n;
                    364:   register core *p;
                    365:   register short *isp1;
                    366:   register short *isp2;
                    367:   register short *iend;
                    368: 
                    369: #ifdef TRACE
                    370:   fprintf(stderr, "Entering new_state, symbol = %d\n", symbol);
                    371: #endif
                    372: 
                    373:   if (nstates >= MAXSHORT)
                    374:     toomany("states");
                    375: 
                    376:   isp1 = kernel_base[symbol];
                    377:   iend = kernel_end[symbol];
                    378:   n = iend - isp1;
                    379: 
                    380:   p = (core *) xmalloc((unsigned) (sizeof(core) + (n - 1) * sizeof(short)));
                    381:   p->accessing_symbol = symbol;
                    382:   p->number = nstates;
                    383:   p->nitems = n;
                    384: 
                    385:   isp2 = p->items;
                    386:   while (isp1 < iend)
                    387:     *isp2++ = *isp1++;
                    388: 
                    389:   last_state->next = p;
                    390:   last_state = p;
                    391: 
                    392:   nstates++;
                    393: 
                    394:   return (p);
                    395: }
                    396: 
                    397: 
                    398: void
                    399: initialize_states()
                    400: {
                    401:   register core *p;
                    402: /*  register unsigned *rp1; JF unused */
                    403: /*  register unsigned *rp2; JF unused */
                    404: /*  register unsigned *rend; JF unused */
                    405: 
                    406:   p = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short)));
                    407:   first_state = last_state = this_state = p;
                    408:   nstates = 1;
                    409: }
                    410: 
                    411: 
                    412: void
                    413: save_shifts()
                    414: {
                    415:   register shifts *p;
                    416:   register short *sp1;
                    417:   register short *sp2;
                    418:   register short *send;
                    419: 
                    420:   p = (shifts *) xmalloc((unsigned) (sizeof(shifts) +
                    421:                                       (nshifts - 1) * sizeof(short)));
                    422: 
                    423:   p->number = this_state->number;
                    424:   p->nshifts = nshifts;
                    425: 
                    426:   sp1 = shiftset;
                    427:   sp2 = p->shifts;
                    428:   send = shiftset + nshifts;
                    429: 
                    430:   while (sp1 < send)
                    431:     *sp2++ = *sp1++;
                    432: 
                    433:   if (last_shift)
                    434:     {
                    435:       last_shift->next = p;
                    436:       last_shift = p;
                    437:     }
                    438:   else
                    439:     {
                    440:       first_shift = p;
                    441:       last_shift = p;
                    442:     }
                    443: }
                    444: 
                    445: 
                    446: 
                    447: /* find which rules can be used for reduction transitions from the current state
                    448:    and make a reductions structure for the state to record their rule numbers.  */
                    449: void
                    450: save_reductions()
                    451: {
                    452:   register short *isp;
                    453:   register short *rp1;
                    454:   register short *rp2;
                    455:   register int item;
                    456:   register int count;
                    457:   register reductions *p;
                    458: 
                    459:   short *rend;
                    460: 
                    461:   /* find and count the active items that represent ends of rules */
                    462: 
                    463:   count = 0;
                    464:   for (isp = itemset; isp < itemsetend; isp++)
                    465:     {
                    466:       item = ritem[*isp];
                    467:       if (item < 0)
                    468:        {
                    469:          redset[count++] = -item;
                    470:        }
                    471:     }
                    472: 
                    473:   /* make a reductions structure and copy the data into it.  */
                    474: 
                    475:   if (count)
                    476:     {
                    477:       p = (reductions *) xmalloc((unsigned) (sizeof(reductions) +
                    478:                                               (count - 1) * sizeof(short)));
                    479: 
                    480:       p->number = this_state->number;
                    481:       p->nreds = count;
                    482: 
                    483:       rp1 = redset;
                    484:       rp2 = p->rules;
                    485:       rend = rp1 + count;
                    486: 
                    487:       while (rp1 < rend)
                    488:        *rp2++ = *rp1++;
                    489: 
                    490:       if (last_reduction)
                    491:        {
                    492:          last_reduction->next = p;
                    493:          last_reduction = p;
                    494:        }
                    495:       else
                    496:        {
                    497:          first_reduction = p;
                    498:          last_reduction = p;
                    499:        }
                    500:     }
                    501: }
                    502: 
                    503: 
                    504: 
                    505: /* Make sure that the initial state has a shift that accepts the
                    506: grammar's start symbol and goes to the next-to-final state,
                    507: which has a shift going to the final state, which has a shift
                    508: to the termination state.
                    509: Create such states and shifts if they don't happen to exist already.  */
                    510: void
                    511: augment_automaton()
                    512: {
                    513:   register int i;
                    514:   register int k;
                    515: /*  register int found; JF unused */
                    516:   register core *statep;
                    517:   register shifts *sp;
                    518:   register shifts *sp2;
                    519:   register shifts *sp1;
                    520: 
                    521:   sp = first_shift;
                    522: 
                    523:   if (sp)
                    524:     {
                    525:       if (sp->number == 0)
                    526:        {
                    527:          k = sp->nshifts;
                    528:          statep = first_state->next;
                    529: 
                    530:          /* The states reached by shifts from first_state are numbered 1...K.
                    531:             Look for one reached by start_symbol.  */
                    532:          while (statep->accessing_symbol < start_symbol
                    533:                  && statep->number < k)
                    534:            statep = statep->next;
                    535: 
                    536:          if (statep->accessing_symbol == start_symbol)
                    537:            {
                    538:              /* We already have a next-to-final state.
                    539:                 Make sure it has a shift to what will be the final state.  */
                    540:              k = statep->number;
                    541: 
                    542:              while (sp && sp->number < k)
                    543:                {
                    544:                  sp1 = sp;
                    545:                  sp = sp->next;
                    546:                }
                    547: 
                    548:              if (sp && sp->number == k)
                    549:                {
                    550:                  sp2 = (shifts *) xmalloc((unsigned) (sizeof(shifts)
                    551:                                                         + sp->nshifts * sizeof(short)));
                    552:                  sp2->number = k;
                    553:                  sp2->nshifts = sp->nshifts + 1;
                    554:                  sp2->shifts[0] = nstates;
                    555:                  for (i = sp->nshifts; i > 0; i--)
                    556:                    sp2->shifts[i] = sp->shifts[i - 1];
                    557: 
                    558:                  /* Patch sp2 into the chain of shifts in place of sp,
                    559:                     following sp1.  */
                    560:                  sp2->next = sp->next;
                    561:                  sp1->next = sp2;
                    562:                  if (sp == last_shift)
                    563:                    last_shift = sp2;
                    564:                  FREE(sp);
                    565:                }
                    566:              else
                    567:                {
                    568:                  sp2 = NEW(shifts);
                    569:                  sp2->number = k;
                    570:                  sp2->nshifts = 1;
                    571:                  sp2->shifts[0] = nstates;
                    572: 
                    573:                  /* Patch sp2 into the chain of shifts between sp1 and sp.  */
                    574:                  sp2->next = sp;
                    575:                  sp1->next = sp2;
                    576:                  if (sp == 0)
                    577:                    last_shift = sp2;
                    578:                }
                    579:            }
                    580:          else
                    581:            {
                    582:              /* There is no next-to-final state as yet.  */
                    583:              /* Add one more shift in first_shift,
                    584:                 going to the next-to-final state (yet to be made).  */
                    585:              sp = first_shift;
                    586: 
                    587:              sp2 = (shifts *) xmalloc(sizeof(shifts)
                    588:                                         + sp->nshifts * sizeof(short));
                    589:              sp2->nshifts = sp->nshifts + 1;
                    590: 
                    591:              /* Stick this shift into the vector at the proper place.  */
                    592:              statep = first_state->next;
                    593:              for (k = 0, i = 0; i < sp->nshifts; k++, i++)
                    594:                {
                    595:                  if (statep->accessing_symbol > start_symbol && i == k)
                    596:                    sp2->shifts[k++] = nstates;
                    597:                  sp2->shifts[k] = sp->shifts[i];
                    598:                  statep = statep->next;
                    599:                }
                    600:              if (i == k)
                    601:                sp2->shifts[k++] = nstates;
                    602: 
                    603:              /* Patch sp2 into the chain of shifts
                    604:                 in place of sp, at the beginning.  */
                    605:              sp2->next = sp->next;
                    606:              first_shift = sp2;
                    607:              if (last_shift == sp)
                    608:                last_shift = sp2;
                    609: 
                    610:              FREE(sp);
                    611: 
                    612:              /* Create the next-to-final state, with shift to
                    613:                 what will be the final state.  */
                    614:              insert_start_shift();
                    615:            }
                    616:        }
                    617:       else
                    618:        {
                    619:          /* The initial state didn't even have any shifts.
                    620:             Give it one shift, to the next-to-final state.  */
                    621:          sp = NEW(shifts);
                    622:          sp->nshifts = 1;
                    623:          sp->shifts[0] = nstates;
                    624: 
                    625:          /* Patch sp into the chain of shifts at the beginning.  */
                    626:          sp->next = first_shift;
                    627:          first_shift = sp;
                    628: 
                    629:          /* Create the next-to-final state, with shift to
                    630:             what will be the final state.  */
                    631:          insert_start_shift();
                    632:        }
                    633:     }
                    634:   else
                    635:     {
                    636:       /* There are no shifts for any state.
                    637:         Make one shift, from the initial state to the next-to-final state.  */
                    638: 
                    639:       sp = NEW(shifts);
                    640:       sp->nshifts = 1;
                    641:       sp->shifts[0] = nstates;
                    642: 
                    643:       /* Initialize the chain of shifts with sp.  */
                    644:       first_shift = sp;
                    645:       last_shift = sp;
                    646: 
                    647:       /* Create the next-to-final state, with shift to
                    648:         what will be the final state.  */
                    649:       insert_start_shift();
                    650:     }
                    651: 
                    652:   /* Make the final state--the one that follows a shift from the
                    653:      next-to-final state.
                    654:      The symbol for that shift is 0 (end-of-file).  */
                    655:   statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short)));
                    656:   statep->number = nstates;
                    657:   last_state->next = statep;
                    658:   last_state = statep;
                    659: 
                    660:   /* Make the shift from the final state to the termination state.  */
                    661:   sp = NEW(shifts);
                    662:   sp->number = nstates++;
                    663:   sp->nshifts = 1;
                    664:   sp->shifts[0] = nstates;
                    665:   last_shift->next = sp;
                    666:   last_shift = sp;
                    667: 
                    668:   /* Note that the variable `final_state' refers to what we sometimes call
                    669:      the termination state.  */
                    670:   final_state = nstates;
                    671: 
                    672:   /* Make the termination state.  */
                    673:   statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short)));
                    674:   statep->number = nstates++;
                    675:   last_state->next = statep;
                    676:   last_state = statep;
                    677: }
                    678: 
                    679: 
                    680: /* subroutine of augment_automaton.
                    681:    Create the next-to-final state, to which a shift has already been made in
                    682:    the initial state.  */
                    683: void
                    684: insert_start_shift()
                    685: {
                    686:   register core *statep;
                    687:   register shifts *sp;
                    688: 
                    689:   statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short)));
                    690:   statep->number = nstates;
                    691:   statep->accessing_symbol = start_symbol;
                    692: 
                    693:   last_state->next = statep;
                    694:   last_state = statep;
                    695: 
                    696:   /* Make a shift from this state to (what will be) the final state.  */
                    697:   sp = NEW(shifts);
                    698:   sp->number = nstates++;
                    699:   sp->nshifts = 1;
                    700:   sp->shifts[0] = nstates;
                    701: 
                    702:   last_shift->next = sp;
                    703:   last_shift = sp;
                    704: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.