Annotation of researchv10dc/cmd/bison/lalr.c, revision 1.1.1.1

1.1       root        1: /* Compute look-ahead criteria for bison,
                      2:    Copyright (C) 1984, 1986 Bob Corbett and Free Software Foundation, Inc.
                      3: 
                      4: BISON is distributed in the hope that it will be useful, but WITHOUT ANY
                      5: WARRANTY.  No author or distributor accepts responsibility to anyone
                      6: for the consequences of using it or for whether it serves any
                      7: particular purpose or works at all, unless he says so in writing.
                      8: Refer to the BISON General Public License for full details.
                      9: 
                     10: Everyone is granted permission to copy, modify and redistribute BISON,
                     11: but only under the conditions described in the BISON General Public
                     12: License.  A copy of this license is supposed to have been given to you
                     13: along with BISON so you can know your rights and responsibilities.  It
                     14: should be in a file named COPYING.  Among other things, the copyright
                     15: notice and this notice must be preserved on all copies.
                     16: 
                     17:  In other words, you are welcome to use, share and improve this program.
                     18:  You are forbidden to forbid anyone else to use, share and improve
                     19:  what you give them.   Help stamp out software-hoarding!  */
                     20: 
                     21: /* Compute how to make the finite state machine deterministic;
                     22:  find which rules need lookahead in each state, and which lookahead tokens they accept.
                     23: 
                     24: lalr(), the entry point, builds these data structures:
                     25: 
                     26: goto_map, from_state and to_state 
                     27:  record each shift transition which accepts a variable (a nonterminal).
                     28: ngotos is the number of such transitions.
                     29: from_state[t] is the state number which a transition leads from
                     30: and to_state[t] is the state number it leads to.
                     31: All the transitions that accept a particular variable are grouped together and
                     32: goto_map[i - ntokens] is the index in from_state and to_state of the first of them.
                     33: 
                     34: consistent[s] is nonzero if no lookahead is needed to decide what to do in state s.
                     35: 
                     36: LAruleno is a vector which records the rules that need lookahead in various states.
                     37: The elements of LAruleno that apply to state s are those from
                     38:  lookaheads[s] through lookaheads[s+1]-1.
                     39: Each element of LAruleno is a rule number.
                     40: 
                     41: If lr is the length of LAruleno, then a number from 0 to lr-1 
                     42: can specify both a rule and a state where the rule might be applied.
                     43: 
                     44: LA is a lr by ntokens matrix of bits.
                     45: LA[l, i] is 1 if the rule LAruleno[l] is applicable in the appropriate state
                     46:  when the next token is symbol i.
                     47: If LA[l, i] and LA[l, j] are both 1 for i != j, it is a conflict.
                     48: */
                     49: 
                     50: #include <stdio.h>
                     51: #include "machine.h"
                     52: #include "types.h"
                     53: #include "state.h"
                     54: #include "new.h"
                     55: #include "gram.h"
                     56: 
                     57: 
                     58: extern short **derives;
                     59: extern char *nullable;
                     60: 
                     61: 
                     62: int tokensetsize;
                     63: short *lookaheads;
                     64: short *LAruleno;
                     65: unsigned *LA;
                     66: short *accessing_symbol;
                     67: char *consistent;
                     68: core **state_table;
                     69: shifts **shift_table;
                     70: reductions **reduction_table;
                     71: short *goto_map;
                     72: short *from_state;
                     73: short *to_state;
                     74: 
                     75: short **transpose();
                     76: 
                     77: 
                     78: static int infinity;
                     79: static int maxrhs;
                     80: static int ngotos;
                     81: static unsigned *F;
                     82: static short **includes;
                     83: static shorts **lookback;
                     84: static short **R;
                     85: static short *INDEX;
                     86: static short *VERTICES;
                     87: static int top;
                     88: 
                     89: 
                     90: 
                     91: lalr()
                     92: {
                     93:   tokensetsize = WORDSIZE(ntokens);
                     94: 
                     95:   set_state_table();
                     96:   set_accessing_symbol();
                     97:   set_shift_table();
                     98:   set_reduction_table();
                     99:   set_maxrhs();
                    100:   initialize_LA();
                    101:   set_goto_map();
                    102:   initialize_F();
                    103:   build_relations();
                    104:   compute_FOLLOWS();
                    105:   compute_lookaheads();
                    106: }
                    107: 
                    108: 
                    109: 
                    110: set_state_table()
                    111: {
                    112:   register core *sp;
                    113: 
                    114:   state_table = NEW2(nstates, core *);
                    115: 
                    116:   for (sp = first_state; sp; sp = sp->next)
                    117:     state_table[sp->number] = sp;
                    118: }
                    119: 
                    120: 
                    121: 
                    122: set_accessing_symbol()
                    123: {
                    124:   register core *sp;
                    125: 
                    126:   accessing_symbol = NEW2(nstates, short);
                    127: 
                    128:   for (sp = first_state; sp; sp = sp->next)
                    129:     accessing_symbol[sp->number] = sp->accessing_symbol;
                    130: }
                    131: 
                    132: 
                    133: 
                    134: set_shift_table()
                    135: {
                    136:   register shifts *sp;
                    137: 
                    138:   shift_table = NEW2(nstates, shifts *);
                    139: 
                    140:   for (sp = first_shift; sp; sp = sp->next)
                    141:     shift_table[sp->number] = sp;
                    142: }
                    143: 
                    144: 
                    145: 
                    146: set_reduction_table()
                    147: {
                    148:   register reductions *rp;
                    149: 
                    150:   reduction_table = NEW2(nstates, reductions *);
                    151: 
                    152:   for (rp = first_reduction; rp; rp = rp->next)
                    153:     reduction_table[rp->number] = rp;
                    154: }
                    155: 
                    156: 
                    157: 
                    158: set_maxrhs()
                    159: {
                    160:   register short *itemp;
                    161:   register int length;
                    162:   register int max;
                    163: 
                    164:   length = 0;
                    165:   max = 0;
                    166:   for (itemp = ritem; *itemp; itemp++)
                    167:     {
                    168:       if (*itemp > 0)
                    169:        {
                    170:          length++;
                    171:        }
                    172:       else
                    173:        {
                    174:          if (length > max) max = length;
                    175:          length = 0;
                    176:        }
                    177:     }
                    178: 
                    179:   maxrhs = max;
                    180: }
                    181: 
                    182: 
                    183: 
                    184: initialize_LA()
                    185: {
                    186:   register int i;
                    187:   register int j;
                    188:   register int count;
                    189:   register reductions *rp;
                    190:   register shifts *sp;
                    191:   register short *np;
                    192: 
                    193:   consistent = NEW2(nstates, char);
                    194:   lookaheads = NEW2(nstates + 1, short);
                    195: 
                    196:   count = 0;
                    197:   for (i = 0; i < nstates; i++)
                    198:     {
                    199:       register int j;
                    200: 
                    201:       lookaheads[i] = count;
                    202: 
                    203:       rp = reduction_table[i];
                    204:       sp = shift_table[i];
                    205:       if (rp && (rp->nreds > 1
                    206:           || (sp && ! ISVAR(accessing_symbol[sp->shifts[0]]))))
                    207:        count += rp->nreds;
                    208:       else
                    209:        consistent[i] = 1;
                    210: 
                    211:       if (sp)
                    212:        for (j = 0; j < sp->nshifts; j++)
                    213:          {
                    214:            if (accessing_symbol[sp->shifts[j]] == error_token_number)
                    215:              {
                    216:                consistent[i] = 0;
                    217:                break;
                    218:              }
                    219:          }
                    220:     }
                    221: 
                    222:   lookaheads[nstates] = count;
                    223: 
                    224:   LA = NEW2(count * tokensetsize, unsigned);
                    225:   LAruleno = NEW2(count, short);
                    226:   lookback = NEW2(count, shorts *);
                    227: 
                    228:   np = LAruleno;
                    229:   for (i = 0; i < nstates; i++)
                    230:     {
                    231:       if (!consistent[i])
                    232:        {
                    233:          if (rp = reduction_table[i])
                    234:            for (j = 0; j < rp->nreds; j++)
                    235:              *np++ = rp->rules[j];
                    236:        }
                    237:     }
                    238: }
                    239: 
                    240: 
                    241: 
                    242: set_goto_map()
                    243: {
                    244:   register shifts *sp;
                    245:   register int i;
                    246:   register int symbol;
                    247:   register int k;
                    248:   register short *temp_map;
                    249:   register int state2;
                    250:   register int state1;
                    251: 
                    252:   goto_map = NEW2(nvars + 1, short) - ntokens;
                    253:   temp_map = NEW2(nvars + 1, short) - ntokens;
                    254: 
                    255:   ngotos = 0;
                    256:   for (sp = first_shift; sp; sp = sp->next)
                    257:     {
                    258:       for (i = sp->nshifts - 1; i >= 0; i--)
                    259:        {
                    260:          symbol = accessing_symbol[sp->shifts[i]];
                    261: 
                    262:          if (ISTOKEN(symbol)) break;
                    263: 
                    264:          if (ngotos == MAXSHORT)
                    265:            toomany("gotos");
                    266: 
                    267:          ngotos++;
                    268:          goto_map[symbol]++;
                    269:         }
                    270:     }
                    271: 
                    272:   k = 0;
                    273:   for (i = ntokens; i < nsyms; i++)
                    274:     {
                    275:       temp_map[i] = k;
                    276:       k += goto_map[i];
                    277:     }
                    278: 
                    279:   for (i = ntokens; i < nsyms; i++)
                    280:     goto_map[i] = temp_map[i];
                    281: 
                    282:   goto_map[nsyms] = ngotos;
                    283:   temp_map[nsyms] = ngotos;
                    284: 
                    285:   from_state = NEW2(ngotos, short);
                    286:   to_state = NEW2(ngotos, short);
                    287: 
                    288:   for (sp = first_shift; sp; sp = sp->next)
                    289:     {
                    290:       state1 = sp->number;
                    291:       for (i = sp->nshifts - 1; i >= 0; i--)
                    292:        {
                    293:          state2 = sp->shifts[i];
                    294:          symbol = accessing_symbol[state2];
                    295: 
                    296:          if (ISTOKEN(symbol)) break;
                    297: 
                    298:          k = temp_map[symbol]++;
                    299:          from_state[k] = state1;
                    300:          to_state[k] = state2;
                    301:        }
                    302:     }
                    303: 
                    304:   FREE(temp_map + ntokens);
                    305: }
                    306: 
                    307: 
                    308: 
                    309: /*  Map_goto maps a state/symbol pair into its numeric representation. */
                    310: 
                    311: int
                    312: map_goto(state, symbol)
                    313: int state;
                    314: int symbol;
                    315: {
                    316:   register int high;
                    317:   register int low;
                    318:   register int middle;
                    319:   register int s;
                    320: 
                    321:   low = goto_map[symbol];
                    322:   high = goto_map[symbol + 1];
                    323: 
                    324:   while (low <= high)
                    325:     {
                    326:       middle = (low + high) / 2;
                    327:       s = from_state[middle];
                    328:       if (s == state)
                    329:        return (middle);
                    330:       else if (s < state)
                    331:        low = middle + 1;
                    332:       else
                    333:        high = middle - 1;
                    334:     }
                    335: 
                    336:   berror("map_goto");
                    337: 
                    338: /* NOTREACHED */
                    339: }
                    340: 
                    341: 
                    342: 
                    343: initialize_F()
                    344: {
                    345:   register int i;
                    346:   register int j;
                    347:   register int k;
                    348:   register shifts *sp;
                    349:   register short *edge;
                    350:   register unsigned *rowp;
                    351:   register short *rp;
                    352:   register short **reads;
                    353:   register int nedges;
                    354:   register int stateno;
                    355:   register int symbol;
                    356:   register int nwords;
                    357: 
                    358:   nwords = ngotos * tokensetsize;
                    359:   F = NEW2(nwords, unsigned);
                    360: 
                    361:   reads = NEW2(ngotos, short *);
                    362:   edge = NEW2(ngotos + 1, short);
                    363:   nedges = 0;
                    364: 
                    365:   rowp = F;
                    366:   for (i = 0; i < ngotos; i++)
                    367:     {
                    368:       stateno = to_state[i];
                    369:       sp = shift_table[stateno];
                    370: 
                    371:       if (sp)
                    372:        {
                    373:          k = sp->nshifts;
                    374: 
                    375:          for (j = 0; j < k; j++)
                    376:            {
                    377:              symbol = accessing_symbol[sp->shifts[j]];
                    378:              if (ISVAR(symbol))
                    379:                break;
                    380:              SETBIT(rowp, symbol);
                    381:            }
                    382: 
                    383:          for (; j < k; j++)
                    384:            {
                    385:              symbol = accessing_symbol[sp->shifts[j]];
                    386:              if (nullable[symbol])
                    387:                edge[nedges++] = map_goto(stateno, symbol);
                    388:            }
                    389:        
                    390:          if (nedges)
                    391:            {
                    392:              reads[i] = rp = NEW2(nedges + 1, short);
                    393: 
                    394:              for (j = 0; j < nedges; j++)
                    395:                rp[j] = edge[j];
                    396: 
                    397:              rp[nedges] = -1;
                    398:              nedges = 0;
                    399:            }
                    400:        }
                    401: 
                    402:       rowp += tokensetsize;
                    403:     }
                    404: 
                    405:   digraph(reads);
                    406: 
                    407:   for (i = 0; i < ngotos; i++)
                    408:     {
                    409:       if (reads[i])
                    410:        FREE(reads[i]);
                    411:     }
                    412: 
                    413:   FREE(reads);
                    414:   FREE(edge);
                    415: }
                    416: 
                    417: 
                    418: 
                    419: build_relations()
                    420: {
                    421:   register int i;
                    422:   register int j;
                    423:   register int k;
                    424:   register short *rulep;
                    425:   register short *rp;
                    426:   register shifts *sp;
                    427:   register int length;
                    428:   register int nedges;
                    429:   register int done;
                    430:   register int state1;
                    431:   register int stateno;
                    432:   register int symbol1;
                    433:   register int symbol2;
                    434:   register short *shortp;
                    435:   register short *edge;
                    436:   register short *states;
                    437:   register short **new_includes;
                    438: 
                    439:   includes = NEW2(ngotos, short *);
                    440:   edge = NEW2(ngotos + 1, short);
                    441:   states = NEW2(maxrhs + 1, short);
                    442: 
                    443:   for (i = 0; i < ngotos; i++)
                    444:     {
                    445:       nedges = 0;
                    446:       state1 = from_state[i];
                    447:       symbol1 = accessing_symbol[to_state[i]];
                    448: 
                    449:       for (rulep = derives[symbol1]; *rulep > 0; rulep++)
                    450:        {
                    451:          length = 1;
                    452:          states[0] = state1;
                    453:          stateno = state1;
                    454: 
                    455:          for (rp = ritem + rrhs[*rulep]; *rp > 0; rp++)
                    456:            {
                    457:              symbol2 = *rp;
                    458:              sp = shift_table[stateno];
                    459:              k = sp->nshifts;
                    460: 
                    461:              for (j = 0; j < k; j++)
                    462:                {
                    463:                  stateno = sp->shifts[j];
                    464:                  if (accessing_symbol[stateno] == symbol2) break;
                    465:                }
                    466: 
                    467:              states[length++] = stateno;
                    468:            }
                    469: 
                    470:          if (!consistent[stateno])
                    471:            add_lookback_edge(stateno, *rulep, i);
                    472: 
                    473:          length--;
                    474:          done = 0;
                    475:          while (!done)
                    476:            {
                    477:              done = 1;
                    478:              rp--;
                    479:                        /* JF added rp>=ritem &&   I hope to god its right! */
                    480:              if (rp>=ritem && ISVAR(*rp))
                    481:                {
                    482:                  stateno = states[--length];
                    483:                  edge[nedges++] = map_goto(stateno, *rp);
                    484:                  if (nullable[*rp]) done = 0;
                    485:                }
                    486:            }
                    487:        }
                    488: 
                    489:       if (nedges)
                    490:        {
                    491:          includes[i] = shortp = NEW2(nedges + 1, short);
                    492:          for (j = 0; j < nedges; j++)
                    493:            shortp[j] = edge[j];
                    494:          shortp[nedges] = -1;
                    495:        }
                    496:     }
                    497: 
                    498:   new_includes = transpose(includes, ngotos);
                    499: 
                    500:   for (i = 0; i < ngotos; i++)
                    501:     if (includes[i])
                    502:       FREE(includes[i]);
                    503: 
                    504:   FREE(includes);
                    505: 
                    506:   includes = new_includes;
                    507: 
                    508:   FREE(edge);
                    509:   FREE(states);
                    510: }
                    511: 
                    512: 
                    513: 
                    514: add_lookback_edge(stateno, ruleno, gotono)
                    515: int stateno;
                    516: int ruleno;
                    517: int gotono;
                    518: {
                    519:   register int i;
                    520:   register int k;
                    521:   register int found;
                    522:   register shorts *sp;
                    523: 
                    524:   i = lookaheads[stateno];
                    525:   k = lookaheads[stateno + 1];
                    526:   found = 0;
                    527:   while (!found && i < k)
                    528:     {
                    529:       if (LAruleno[i] == ruleno)
                    530:        found = 1;
                    531:       else
                    532:        i++;
                    533:     }
                    534: 
                    535:   if (found == 0)
                    536:     berror("add_lookback_edge");
                    537: 
                    538:   sp = NEW(shorts);
                    539:   sp->next = lookback[i];
                    540:   sp->value = gotono;
                    541:   lookback[i] = sp;
                    542: }
                    543: 
                    544: 
                    545: 
                    546: short **
                    547: transpose(R, n)
                    548: short **R;
                    549: int n;
                    550: {
                    551:   register short **new_R;
                    552:   register short **temp_R;
                    553:   register short *nedges;
                    554:   register short *sp;
                    555:   register int i;
                    556:   register int k;
                    557: 
                    558:   nedges = NEW2(n, short);
                    559: 
                    560:   for (i = 0; i < n; i++)
                    561:     {
                    562:       sp = R[i];
                    563:       if (sp)
                    564:        {
                    565:          while (*sp >= 0)
                    566:            nedges[*sp++]++;
                    567:        }
                    568:     }
                    569: 
                    570:   new_R = NEW2(n, short *);
                    571:   temp_R = NEW2(n, short *);
                    572: 
                    573:   for (i = 0; i < n; i++)
                    574:     {
                    575:       k = nedges[i];
                    576:       if (k > 0)
                    577:        {
                    578:          sp = NEW2(k + 1, short);
                    579:          new_R[i] = sp;
                    580:          temp_R[i] = sp;
                    581:          sp[k] = -1;
                    582:        }
                    583:     }
                    584: 
                    585:   FREE(nedges);
                    586: 
                    587:   for (i = 0; i < n; i++)
                    588:     {
                    589:       sp = R[i];
                    590:       if (sp)
                    591:        {
                    592:          while (*sp >= 0)
                    593:            *temp_R[*sp++]++ = i;
                    594:        }
                    595:     }
                    596: 
                    597:   FREE(temp_R);
                    598: 
                    599:   return (new_R);
                    600: }
                    601: 
                    602: 
                    603: 
                    604: compute_FOLLOWS()
                    605: {
                    606:   register int i;
                    607: 
                    608:   digraph(includes);
                    609: 
                    610:   for (i = 0; i < ngotos; i++)
                    611:     {
                    612:       if (includes[i]) FREE(includes[i]);
                    613:     }
                    614: 
                    615:   FREE(includes);
                    616: }
                    617: 
                    618: 
                    619: 
                    620: compute_lookaheads()
                    621: {
                    622:   register int i;
                    623:   register int n;
                    624:   register unsigned *fp1;
                    625:   register unsigned *fp2;
                    626:   register unsigned *fp3;
                    627:   register shorts *sp;
                    628:   register unsigned *rowp;
                    629: /*   register short *rulep; JF unused */
                    630: /*  register int count; JF unused */
                    631:   register shorts *sptmp;/* JF */
                    632: 
                    633:   rowp = LA;
                    634:   n = lookaheads[nstates];
                    635:   for (i = 0; i < n; i++)
                    636:     {
                    637:       fp3 = rowp + tokensetsize;
                    638:       for (sp = lookback[i]; sp; sp = sp->next)
                    639:        {
                    640:          fp1 = rowp;
                    641:          fp2 = F + tokensetsize * sp->value;
                    642:          while (fp1 < fp3)
                    643:            *fp1++ |= *fp2++;
                    644:        }
                    645: 
                    646:       rowp = fp3;
                    647:     }
                    648: 
                    649:   for (i = 0; i < n; i++)
                    650:     {/* JF removed ref to freed storage */
                    651:       for (sp = lookback[i]; sp; sp = sptmp) {
                    652:        sptmp=sp->next;
                    653:        FREE(sp);
                    654:       }
                    655:     }
                    656: 
                    657:   FREE(lookback);
                    658:   FREE(F);
                    659: }
                    660: 
                    661: 
                    662: 
                    663: digraph(relation)
                    664: short **relation;
                    665: {
                    666:   register int i;
                    667: 
                    668:   infinity = ngotos + 2;
                    669:   INDEX = NEW2(ngotos + 1, short);
                    670:   VERTICES = NEW2(ngotos + 1, short);
                    671:   top = 0;
                    672: 
                    673:   R = relation;
                    674: 
                    675:   for (i = 0; i < ngotos; i++)
                    676:     INDEX[i] = 0;
                    677: 
                    678:   for (i = 0; i < ngotos; i++)
                    679:     {
                    680:       if (INDEX[i] == 0 && R[i])
                    681:        traverse(i);
                    682:     }
                    683: 
                    684:   FREE(INDEX);
                    685:   FREE(VERTICES);
                    686: }
                    687: 
                    688: 
                    689: 
                    690: traverse(i)
                    691: register int i;
                    692: {
                    693:   register unsigned *fp1;
                    694:   register unsigned *fp2;
                    695:   register unsigned *fp3;
                    696:   register int j;
                    697:   register short *rp;
                    698: 
                    699:   int height;
                    700:   unsigned *base;
                    701: 
                    702:   VERTICES[++top] = i;
                    703:   INDEX[i] = height = top;
                    704: 
                    705:   base = F + i * tokensetsize;
                    706:   fp3 = base + tokensetsize;
                    707: 
                    708:   rp = R[i];
                    709:   if (rp)
                    710:     {
                    711:       while ((j = *rp++) >= 0)
                    712:        {
                    713:          if (INDEX[j] == 0)
                    714:            traverse(j);
                    715: 
                    716:          if (INDEX[i] > INDEX[j])
                    717:            INDEX[i] = INDEX[j];
                    718: 
                    719:          fp1 = base;
                    720:          fp2 = F + j * tokensetsize;
                    721: 
                    722:          while (fp1 < fp3)
                    723:            *fp1++ |= *fp2++;
                    724:        }
                    725:     }
                    726: 
                    727:   if (INDEX[i] == height)
                    728:     {
                    729:       for (;;)
                    730:        {
                    731:          j = VERTICES[top--];
                    732:          INDEX[j] = infinity;
                    733: 
                    734:          if (i == j)
                    735:            break;
                    736: 
                    737:          fp1 = base;
                    738:          fp2 = F + j * tokensetsize;
                    739: 
                    740:          while (fp1 < fp3)
                    741:            *fp2++ = *fp1++;
                    742:        }
                    743:     }
                    744: }

unix.superglobalmegacorp.com

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