Home | History | Annotate | Line # | Download | only in dist
lalr.c revision 1.1.1.4
      1  1.1.1.3  christos /*	$NetBSD: lalr.c,v 1.1.1.4 2013/04/06 14:45:26 christos Exp $	*/
      2  1.1.1.3  christos 
      3  1.1.1.4  christos /* Id: lalr.c,v 1.9 2009/10/27 09:49:27 tom Exp  */
      4      1.1  christos 
      5      1.1  christos #include "defs.h"
      6      1.1  christos 
      7      1.1  christos typedef struct shorts
      8      1.1  christos {
      9      1.1  christos     struct shorts *next;
     10      1.1  christos     Value_t value;
     11      1.1  christos }
     12      1.1  christos shorts;
     13      1.1  christos 
     14      1.1  christos static Value_t map_goto(int state, int symbol);
     15      1.1  christos static Value_t **transpose(Value_t ** R, int n);
     16      1.1  christos static void add_lookback_edge(int stateno, int ruleno, int gotono);
     17      1.1  christos static void build_relations(void);
     18      1.1  christos static void compute_FOLLOWS(void);
     19      1.1  christos static void compute_lookaheads(void);
     20      1.1  christos static void digraph(Value_t ** relation);
     21      1.1  christos static void initialize_F(void);
     22      1.1  christos static void initialize_LA(void);
     23      1.1  christos static void set_accessing_symbol(void);
     24      1.1  christos static void set_goto_map(void);
     25      1.1  christos static void set_maxrhs(void);
     26      1.1  christos static void set_reduction_table(void);
     27      1.1  christos static void set_shift_table(void);
     28      1.1  christos static void set_state_table(void);
     29      1.1  christos static void traverse(int i);
     30      1.1  christos 
     31      1.1  christos static int tokensetsize;
     32      1.1  christos Value_t *lookaheads;
     33      1.1  christos Value_t *LAruleno;
     34      1.1  christos unsigned *LA;
     35      1.1  christos Value_t *accessing_symbol;
     36      1.1  christos core **state_table;
     37      1.1  christos shifts **shift_table;
     38      1.1  christos reductions **reduction_table;
     39      1.1  christos Value_t *goto_map;
     40      1.1  christos Value_t *from_state;
     41      1.1  christos Value_t *to_state;
     42      1.1  christos 
     43      1.1  christos static Value_t infinity;
     44      1.1  christos static int maxrhs;
     45      1.1  christos static int ngotos;
     46      1.1  christos static unsigned *F;
     47      1.1  christos static Value_t **includes;
     48      1.1  christos static shorts **lookback;
     49      1.1  christos static Value_t **R;
     50      1.1  christos static Value_t *INDEX;
     51      1.1  christos static Value_t *VERTICES;
     52      1.1  christos static Value_t top;
     53      1.1  christos 
     54      1.1  christos void
     55      1.1  christos lalr(void)
     56      1.1  christos {
     57      1.1  christos     tokensetsize = WORDSIZE(ntokens);
     58      1.1  christos 
     59      1.1  christos     set_state_table();
     60      1.1  christos     set_accessing_symbol();
     61      1.1  christos     set_shift_table();
     62      1.1  christos     set_reduction_table();
     63      1.1  christos     set_maxrhs();
     64      1.1  christos     initialize_LA();
     65      1.1  christos     set_goto_map();
     66      1.1  christos     initialize_F();
     67      1.1  christos     build_relations();
     68      1.1  christos     compute_FOLLOWS();
     69      1.1  christos     compute_lookaheads();
     70      1.1  christos }
     71      1.1  christos 
     72      1.1  christos static void
     73      1.1  christos set_state_table(void)
     74      1.1  christos {
     75      1.1  christos     core *sp;
     76      1.1  christos 
     77      1.1  christos     state_table = NEW2(nstates, core *);
     78      1.1  christos     for (sp = first_state; sp; sp = sp->next)
     79      1.1  christos 	state_table[sp->number] = sp;
     80      1.1  christos }
     81      1.1  christos 
     82      1.1  christos static void
     83      1.1  christos set_accessing_symbol(void)
     84      1.1  christos {
     85      1.1  christos     core *sp;
     86      1.1  christos 
     87      1.1  christos     accessing_symbol = NEW2(nstates, Value_t);
     88      1.1  christos     for (sp = first_state; sp; sp = sp->next)
     89      1.1  christos 	accessing_symbol[sp->number] = sp->accessing_symbol;
     90      1.1  christos }
     91      1.1  christos 
     92      1.1  christos static void
     93      1.1  christos set_shift_table(void)
     94      1.1  christos {
     95      1.1  christos     shifts *sp;
     96      1.1  christos 
     97      1.1  christos     shift_table = NEW2(nstates, shifts *);
     98      1.1  christos     for (sp = first_shift; sp; sp = sp->next)
     99      1.1  christos 	shift_table[sp->number] = sp;
    100      1.1  christos }
    101      1.1  christos 
    102      1.1  christos static void
    103      1.1  christos set_reduction_table(void)
    104      1.1  christos {
    105      1.1  christos     reductions *rp;
    106      1.1  christos 
    107      1.1  christos     reduction_table = NEW2(nstates, reductions *);
    108      1.1  christos     for (rp = first_reduction; rp; rp = rp->next)
    109      1.1  christos 	reduction_table[rp->number] = rp;
    110      1.1  christos }
    111      1.1  christos 
    112      1.1  christos static void
    113      1.1  christos set_maxrhs(void)
    114      1.1  christos {
    115      1.1  christos     Value_t *itemp;
    116      1.1  christos     Value_t *item_end;
    117      1.1  christos     int length;
    118      1.1  christos     int max;
    119      1.1  christos 
    120      1.1  christos     length = 0;
    121      1.1  christos     max = 0;
    122      1.1  christos     item_end = ritem + nitems;
    123      1.1  christos     for (itemp = ritem; itemp < item_end; itemp++)
    124      1.1  christos     {
    125      1.1  christos 	if (*itemp >= 0)
    126      1.1  christos 	{
    127      1.1  christos 	    length++;
    128      1.1  christos 	}
    129      1.1  christos 	else
    130      1.1  christos 	{
    131      1.1  christos 	    if (length > max)
    132      1.1  christos 		max = length;
    133      1.1  christos 	    length = 0;
    134      1.1  christos 	}
    135      1.1  christos     }
    136      1.1  christos 
    137      1.1  christos     maxrhs = max;
    138      1.1  christos }
    139      1.1  christos 
    140      1.1  christos static void
    141      1.1  christos initialize_LA(void)
    142      1.1  christos {
    143      1.1  christos     int i, j, k;
    144      1.1  christos     reductions *rp;
    145      1.1  christos 
    146      1.1  christos     lookaheads = NEW2(nstates + 1, Value_t);
    147      1.1  christos 
    148      1.1  christos     k = 0;
    149      1.1  christos     for (i = 0; i < nstates; i++)
    150      1.1  christos     {
    151      1.1  christos 	lookaheads[i] = (Value_t) k;
    152      1.1  christos 	rp = reduction_table[i];
    153      1.1  christos 	if (rp)
    154      1.1  christos 	    k += rp->nreds;
    155      1.1  christos     }
    156      1.1  christos     lookaheads[nstates] = (Value_t) k;
    157      1.1  christos 
    158      1.1  christos     LA = NEW2(k * tokensetsize, unsigned);
    159      1.1  christos     LAruleno = NEW2(k, Value_t);
    160      1.1  christos     lookback = NEW2(k, shorts *);
    161      1.1  christos 
    162      1.1  christos     k = 0;
    163      1.1  christos     for (i = 0; i < nstates; i++)
    164      1.1  christos     {
    165      1.1  christos 	rp = reduction_table[i];
    166      1.1  christos 	if (rp)
    167      1.1  christos 	{
    168      1.1  christos 	    for (j = 0; j < rp->nreds; j++)
    169      1.1  christos 	    {
    170      1.1  christos 		LAruleno[k] = rp->rules[j];
    171      1.1  christos 		k++;
    172      1.1  christos 	    }
    173      1.1  christos 	}
    174      1.1  christos     }
    175      1.1  christos }
    176      1.1  christos 
    177      1.1  christos static void
    178      1.1  christos set_goto_map(void)
    179      1.1  christos {
    180      1.1  christos     shifts *sp;
    181      1.1  christos     int i;
    182      1.1  christos     int symbol;
    183      1.1  christos     int k;
    184      1.1  christos     Value_t *temp_map;
    185      1.1  christos     Value_t state2;
    186      1.1  christos     Value_t state1;
    187      1.1  christos 
    188      1.1  christos     goto_map = NEW2(nvars + 1, Value_t) - ntokens;
    189      1.1  christos     temp_map = NEW2(nvars + 1, Value_t) - ntokens;
    190      1.1  christos 
    191      1.1  christos     ngotos = 0;
    192      1.1  christos     for (sp = first_shift; sp; sp = sp->next)
    193      1.1  christos     {
    194      1.1  christos 	for (i = sp->nshifts - 1; i >= 0; i--)
    195      1.1  christos 	{
    196      1.1  christos 	    symbol = accessing_symbol[sp->shift[i]];
    197      1.1  christos 
    198      1.1  christos 	    if (ISTOKEN(symbol))
    199      1.1  christos 		break;
    200      1.1  christos 
    201      1.1  christos 	    if (ngotos == MAXSHORT)
    202      1.1  christos 		fatal("too many gotos");
    203      1.1  christos 
    204      1.1  christos 	    ngotos++;
    205      1.1  christos 	    goto_map[symbol]++;
    206      1.1  christos 	}
    207      1.1  christos     }
    208      1.1  christos 
    209      1.1  christos     k = 0;
    210      1.1  christos     for (i = ntokens; i < nsyms; i++)
    211      1.1  christos     {
    212      1.1  christos 	temp_map[i] = (Value_t) k;
    213      1.1  christos 	k += goto_map[i];
    214      1.1  christos     }
    215      1.1  christos 
    216      1.1  christos     for (i = ntokens; i < nsyms; i++)
    217      1.1  christos 	goto_map[i] = temp_map[i];
    218      1.1  christos 
    219      1.1  christos     goto_map[nsyms] = (Value_t) ngotos;
    220      1.1  christos     temp_map[nsyms] = (Value_t) ngotos;
    221      1.1  christos 
    222      1.1  christos     from_state = NEW2(ngotos, Value_t);
    223      1.1  christos     to_state = NEW2(ngotos, Value_t);
    224      1.1  christos 
    225      1.1  christos     for (sp = first_shift; sp; sp = sp->next)
    226      1.1  christos     {
    227      1.1  christos 	state1 = sp->number;
    228      1.1  christos 	for (i = sp->nshifts - 1; i >= 0; i--)
    229      1.1  christos 	{
    230      1.1  christos 	    state2 = sp->shift[i];
    231      1.1  christos 	    symbol = accessing_symbol[state2];
    232      1.1  christos 
    233      1.1  christos 	    if (ISTOKEN(symbol))
    234      1.1  christos 		break;
    235      1.1  christos 
    236      1.1  christos 	    k = temp_map[symbol]++;
    237      1.1  christos 	    from_state[k] = state1;
    238      1.1  christos 	    to_state[k] = state2;
    239      1.1  christos 	}
    240      1.1  christos     }
    241      1.1  christos 
    242      1.1  christos     FREE(temp_map + ntokens);
    243      1.1  christos }
    244      1.1  christos 
    245      1.1  christos /*  Map_goto maps a state/symbol pair into its numeric representation.	*/
    246      1.1  christos 
    247      1.1  christos static Value_t
    248      1.1  christos map_goto(int state, int symbol)
    249      1.1  christos {
    250      1.1  christos     int high;
    251      1.1  christos     int low;
    252      1.1  christos     int middle;
    253      1.1  christos     int s;
    254      1.1  christos 
    255      1.1  christos     low = goto_map[symbol];
    256      1.1  christos     high = goto_map[symbol + 1];
    257      1.1  christos 
    258      1.1  christos     for (;;)
    259      1.1  christos     {
    260      1.1  christos 	assert(low <= high);
    261      1.1  christos 	middle = (low + high) >> 1;
    262      1.1  christos 	s = from_state[middle];
    263      1.1  christos 	if (s == state)
    264      1.1  christos 	    return (Value_t) (middle);
    265      1.1  christos 	else if (s < state)
    266      1.1  christos 	    low = middle + 1;
    267      1.1  christos 	else
    268      1.1  christos 	    high = middle - 1;
    269      1.1  christos     }
    270      1.1  christos }
    271      1.1  christos 
    272      1.1  christos static void
    273      1.1  christos initialize_F(void)
    274      1.1  christos {
    275      1.1  christos     int i;
    276      1.1  christos     int j;
    277      1.1  christos     int k;
    278      1.1  christos     shifts *sp;
    279      1.1  christos     Value_t *edge;
    280      1.1  christos     unsigned *rowp;
    281      1.1  christos     Value_t *rp;
    282      1.1  christos     Value_t **reads;
    283      1.1  christos     int nedges;
    284      1.1  christos     int stateno;
    285      1.1  christos     int symbol;
    286      1.1  christos     int nwords;
    287      1.1  christos 
    288      1.1  christos     nwords = ngotos * tokensetsize;
    289      1.1  christos     F = NEW2(nwords, unsigned);
    290      1.1  christos 
    291      1.1  christos     reads = NEW2(ngotos, Value_t *);
    292      1.1  christos     edge = NEW2(ngotos + 1, Value_t);
    293      1.1  christos     nedges = 0;
    294      1.1  christos 
    295      1.1  christos     rowp = F;
    296      1.1  christos     for (i = 0; i < ngotos; i++)
    297      1.1  christos     {
    298      1.1  christos 	stateno = to_state[i];
    299      1.1  christos 	sp = shift_table[stateno];
    300      1.1  christos 
    301      1.1  christos 	if (sp)
    302      1.1  christos 	{
    303      1.1  christos 	    k = sp->nshifts;
    304      1.1  christos 
    305      1.1  christos 	    for (j = 0; j < k; j++)
    306      1.1  christos 	    {
    307      1.1  christos 		symbol = accessing_symbol[sp->shift[j]];
    308      1.1  christos 		if (ISVAR(symbol))
    309      1.1  christos 		    break;
    310      1.1  christos 		SETBIT(rowp, symbol);
    311      1.1  christos 	    }
    312      1.1  christos 
    313      1.1  christos 	    for (; j < k; j++)
    314      1.1  christos 	    {
    315      1.1  christos 		symbol = accessing_symbol[sp->shift[j]];
    316      1.1  christos 		if (nullable[symbol])
    317      1.1  christos 		    edge[nedges++] = map_goto(stateno, symbol);
    318      1.1  christos 	    }
    319      1.1  christos 
    320      1.1  christos 	    if (nedges)
    321      1.1  christos 	    {
    322      1.1  christos 		reads[i] = rp = NEW2(nedges + 1, Value_t);
    323      1.1  christos 
    324      1.1  christos 		for (j = 0; j < nedges; j++)
    325      1.1  christos 		    rp[j] = edge[j];
    326      1.1  christos 
    327      1.1  christos 		rp[nedges] = -1;
    328      1.1  christos 		nedges = 0;
    329      1.1  christos 	    }
    330      1.1  christos 	}
    331      1.1  christos 
    332      1.1  christos 	rowp += tokensetsize;
    333      1.1  christos     }
    334      1.1  christos 
    335      1.1  christos     SETBIT(F, 0);
    336      1.1  christos     digraph(reads);
    337      1.1  christos 
    338      1.1  christos     for (i = 0; i < ngotos; i++)
    339      1.1  christos     {
    340      1.1  christos 	if (reads[i])
    341      1.1  christos 	    FREE(reads[i]);
    342      1.1  christos     }
    343      1.1  christos 
    344      1.1  christos     FREE(reads);
    345      1.1  christos     FREE(edge);
    346      1.1  christos }
    347      1.1  christos 
    348      1.1  christos static void
    349      1.1  christos build_relations(void)
    350      1.1  christos {
    351      1.1  christos     int i;
    352      1.1  christos     int j;
    353      1.1  christos     int k;
    354      1.1  christos     Value_t *rulep;
    355      1.1  christos     Value_t *rp;
    356      1.1  christos     shifts *sp;
    357      1.1  christos     int length;
    358      1.1  christos     int nedges;
    359      1.1  christos     int done_flag;
    360      1.1  christos     Value_t state1;
    361      1.1  christos     Value_t stateno;
    362      1.1  christos     int symbol1;
    363      1.1  christos     int symbol2;
    364      1.1  christos     Value_t *shortp;
    365      1.1  christos     Value_t *edge;
    366      1.1  christos     Value_t *states;
    367      1.1  christos     Value_t **new_includes;
    368      1.1  christos 
    369      1.1  christos     includes = NEW2(ngotos, Value_t *);
    370      1.1  christos     edge = NEW2(ngotos + 1, Value_t);
    371      1.1  christos     states = NEW2(maxrhs + 1, Value_t);
    372      1.1  christos 
    373      1.1  christos     for (i = 0; i < ngotos; i++)
    374      1.1  christos     {
    375      1.1  christos 	nedges = 0;
    376      1.1  christos 	state1 = from_state[i];
    377      1.1  christos 	symbol1 = accessing_symbol[to_state[i]];
    378      1.1  christos 
    379      1.1  christos 	for (rulep = derives[symbol1]; *rulep >= 0; rulep++)
    380      1.1  christos 	{
    381      1.1  christos 	    length = 1;
    382      1.1  christos 	    states[0] = state1;
    383      1.1  christos 	    stateno = state1;
    384      1.1  christos 
    385      1.1  christos 	    for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++)
    386      1.1  christos 	    {
    387      1.1  christos 		symbol2 = *rp;
    388      1.1  christos 		sp = shift_table[stateno];
    389      1.1  christos 		k = sp->nshifts;
    390      1.1  christos 
    391      1.1  christos 		for (j = 0; j < k; j++)
    392      1.1  christos 		{
    393      1.1  christos 		    stateno = sp->shift[j];
    394      1.1  christos 		    if (accessing_symbol[stateno] == symbol2)
    395      1.1  christos 			break;
    396      1.1  christos 		}
    397      1.1  christos 
    398      1.1  christos 		states[length++] = stateno;
    399      1.1  christos 	    }
    400      1.1  christos 
    401      1.1  christos 	    add_lookback_edge(stateno, *rulep, i);
    402      1.1  christos 
    403      1.1  christos 	    length--;
    404      1.1  christos 	    done_flag = 0;
    405      1.1  christos 	    while (!done_flag)
    406      1.1  christos 	    {
    407      1.1  christos 		done_flag = 1;
    408      1.1  christos 		rp--;
    409      1.1  christos 		if (ISVAR(*rp))
    410      1.1  christos 		{
    411      1.1  christos 		    stateno = states[--length];
    412      1.1  christos 		    edge[nedges++] = map_goto(stateno, *rp);
    413      1.1  christos 		    if (nullable[*rp] && length > 0)
    414      1.1  christos 			done_flag = 0;
    415      1.1  christos 		}
    416      1.1  christos 	    }
    417      1.1  christos 	}
    418      1.1  christos 
    419      1.1  christos 	if (nedges)
    420      1.1  christos 	{
    421      1.1  christos 	    includes[i] = shortp = NEW2(nedges + 1, Value_t);
    422      1.1  christos 	    for (j = 0; j < nedges; j++)
    423      1.1  christos 		shortp[j] = edge[j];
    424      1.1  christos 	    shortp[nedges] = -1;
    425      1.1  christos 	}
    426      1.1  christos     }
    427      1.1  christos 
    428      1.1  christos     new_includes = transpose(includes, ngotos);
    429      1.1  christos 
    430      1.1  christos     for (i = 0; i < ngotos; i++)
    431      1.1  christos 	if (includes[i])
    432      1.1  christos 	    FREE(includes[i]);
    433      1.1  christos 
    434      1.1  christos     FREE(includes);
    435      1.1  christos 
    436      1.1  christos     includes = new_includes;
    437      1.1  christos 
    438      1.1  christos     FREE(edge);
    439      1.1  christos     FREE(states);
    440      1.1  christos }
    441      1.1  christos 
    442      1.1  christos static void
    443      1.1  christos add_lookback_edge(int stateno, int ruleno, int gotono)
    444      1.1  christos {
    445      1.1  christos     int i, k;
    446      1.1  christos     int found;
    447      1.1  christos     shorts *sp;
    448      1.1  christos 
    449      1.1  christos     i = lookaheads[stateno];
    450      1.1  christos     k = lookaheads[stateno + 1];
    451      1.1  christos     found = 0;
    452      1.1  christos     while (!found && i < k)
    453      1.1  christos     {
    454      1.1  christos 	if (LAruleno[i] == ruleno)
    455      1.1  christos 	    found = 1;
    456      1.1  christos 	else
    457      1.1  christos 	    ++i;
    458      1.1  christos     }
    459      1.1  christos     assert(found);
    460      1.1  christos 
    461      1.1  christos     sp = NEW(shorts);
    462      1.1  christos     sp->next = lookback[i];
    463      1.1  christos     sp->value = (Value_t) gotono;
    464      1.1  christos     lookback[i] = sp;
    465      1.1  christos }
    466      1.1  christos 
    467      1.1  christos static Value_t **
    468      1.1  christos transpose(Value_t ** R2, int n)
    469      1.1  christos {
    470      1.1  christos     Value_t **new_R;
    471      1.1  christos     Value_t **temp_R;
    472      1.1  christos     Value_t *nedges;
    473      1.1  christos     Value_t *sp;
    474      1.1  christos     int i;
    475      1.1  christos     int k;
    476      1.1  christos 
    477      1.1  christos     nedges = NEW2(n, Value_t);
    478      1.1  christos 
    479      1.1  christos     for (i = 0; i < n; i++)
    480      1.1  christos     {
    481      1.1  christos 	sp = R2[i];
    482      1.1  christos 	if (sp)
    483      1.1  christos 	{
    484      1.1  christos 	    while (*sp >= 0)
    485      1.1  christos 		nedges[*sp++]++;
    486      1.1  christos 	}
    487      1.1  christos     }
    488      1.1  christos 
    489      1.1  christos     new_R = NEW2(n, Value_t *);
    490      1.1  christos     temp_R = NEW2(n, Value_t *);
    491      1.1  christos 
    492      1.1  christos     for (i = 0; i < n; i++)
    493      1.1  christos     {
    494      1.1  christos 	k = nedges[i];
    495      1.1  christos 	if (k > 0)
    496      1.1  christos 	{
    497      1.1  christos 	    sp = NEW2(k + 1, Value_t);
    498      1.1  christos 	    new_R[i] = sp;
    499      1.1  christos 	    temp_R[i] = sp;
    500      1.1  christos 	    sp[k] = -1;
    501      1.1  christos 	}
    502      1.1  christos     }
    503      1.1  christos 
    504      1.1  christos     FREE(nedges);
    505      1.1  christos 
    506      1.1  christos     for (i = 0; i < n; i++)
    507      1.1  christos     {
    508      1.1  christos 	sp = R2[i];
    509      1.1  christos 	if (sp)
    510      1.1  christos 	{
    511      1.1  christos 	    while (*sp >= 0)
    512      1.1  christos 		*temp_R[*sp++]++ = (Value_t) i;
    513      1.1  christos 	}
    514      1.1  christos     }
    515      1.1  christos 
    516      1.1  christos     FREE(temp_R);
    517      1.1  christos 
    518      1.1  christos     return (new_R);
    519      1.1  christos }
    520      1.1  christos 
    521      1.1  christos static void
    522      1.1  christos compute_FOLLOWS(void)
    523      1.1  christos {
    524      1.1  christos     digraph(includes);
    525      1.1  christos }
    526      1.1  christos 
    527      1.1  christos static void
    528      1.1  christos compute_lookaheads(void)
    529      1.1  christos {
    530      1.1  christos     int i, n;
    531      1.1  christos     unsigned *fp1, *fp2, *fp3;
    532      1.1  christos     shorts *sp, *next;
    533      1.1  christos     unsigned *rowp;
    534      1.1  christos 
    535      1.1  christos     rowp = LA;
    536      1.1  christos     n = lookaheads[nstates];
    537      1.1  christos     for (i = 0; i < n; i++)
    538      1.1  christos     {
    539      1.1  christos 	fp3 = rowp + tokensetsize;
    540      1.1  christos 	for (sp = lookback[i]; sp; sp = sp->next)
    541      1.1  christos 	{
    542      1.1  christos 	    fp1 = rowp;
    543      1.1  christos 	    fp2 = F + tokensetsize * sp->value;
    544      1.1  christos 	    while (fp1 < fp3)
    545      1.1  christos 		*fp1++ |= *fp2++;
    546      1.1  christos 	}
    547      1.1  christos 	rowp = fp3;
    548      1.1  christos     }
    549      1.1  christos 
    550      1.1  christos     for (i = 0; i < n; i++)
    551      1.1  christos 	for (sp = lookback[i]; sp; sp = next)
    552      1.1  christos 	{
    553      1.1  christos 	    next = sp->next;
    554      1.1  christos 	    FREE(sp);
    555      1.1  christos 	}
    556      1.1  christos 
    557      1.1  christos     FREE(lookback);
    558      1.1  christos     FREE(F);
    559      1.1  christos }
    560      1.1  christos 
    561      1.1  christos static void
    562      1.1  christos digraph(Value_t ** relation)
    563      1.1  christos {
    564      1.1  christos     int i;
    565      1.1  christos 
    566      1.1  christos     infinity = (Value_t) (ngotos + 2);
    567      1.1  christos     INDEX = NEW2(ngotos + 1, Value_t);
    568      1.1  christos     VERTICES = NEW2(ngotos + 1, Value_t);
    569      1.1  christos     top = 0;
    570      1.1  christos 
    571      1.1  christos     R = relation;
    572      1.1  christos 
    573      1.1  christos     for (i = 0; i < ngotos; i++)
    574      1.1  christos 	INDEX[i] = 0;
    575      1.1  christos 
    576      1.1  christos     for (i = 0; i < ngotos; i++)
    577      1.1  christos     {
    578      1.1  christos 	if (INDEX[i] == 0 && R[i])
    579      1.1  christos 	    traverse(i);
    580      1.1  christos     }
    581      1.1  christos 
    582      1.1  christos     FREE(INDEX);
    583      1.1  christos     FREE(VERTICES);
    584      1.1  christos }
    585      1.1  christos 
    586      1.1  christos static void
    587      1.1  christos traverse(int i)
    588      1.1  christos {
    589      1.1  christos     unsigned *fp1;
    590      1.1  christos     unsigned *fp2;
    591      1.1  christos     unsigned *fp3;
    592      1.1  christos     int j;
    593      1.1  christos     Value_t *rp;
    594      1.1  christos 
    595      1.1  christos     Value_t height;
    596      1.1  christos     unsigned *base;
    597      1.1  christos 
    598      1.1  christos     VERTICES[++top] = (Value_t) i;
    599      1.1  christos     INDEX[i] = height = top;
    600      1.1  christos 
    601      1.1  christos     base = F + i * tokensetsize;
    602      1.1  christos     fp3 = base + tokensetsize;
    603      1.1  christos 
    604      1.1  christos     rp = R[i];
    605      1.1  christos     if (rp)
    606      1.1  christos     {
    607      1.1  christos 	while ((j = *rp++) >= 0)
    608      1.1  christos 	{
    609      1.1  christos 	    if (INDEX[j] == 0)
    610      1.1  christos 		traverse(j);
    611      1.1  christos 
    612      1.1  christos 	    if (INDEX[i] > INDEX[j])
    613      1.1  christos 		INDEX[i] = INDEX[j];
    614      1.1  christos 
    615      1.1  christos 	    fp1 = base;
    616      1.1  christos 	    fp2 = F + j * tokensetsize;
    617      1.1  christos 
    618      1.1  christos 	    while (fp1 < fp3)
    619      1.1  christos 		*fp1++ |= *fp2++;
    620      1.1  christos 	}
    621      1.1  christos     }
    622      1.1  christos 
    623      1.1  christos     if (INDEX[i] == height)
    624      1.1  christos     {
    625      1.1  christos 	for (;;)
    626      1.1  christos 	{
    627      1.1  christos 	    j = VERTICES[top--];
    628      1.1  christos 	    INDEX[j] = infinity;
    629      1.1  christos 
    630      1.1  christos 	    if (i == j)
    631      1.1  christos 		break;
    632      1.1  christos 
    633      1.1  christos 	    fp1 = base;
    634      1.1  christos 	    fp2 = F + j * tokensetsize;
    635      1.1  christos 
    636      1.1  christos 	    while (fp1 < fp3)
    637      1.1  christos 		*fp2++ = *fp1++;
    638      1.1  christos 	}
    639      1.1  christos     }
    640      1.1  christos }
    641      1.1  christos 
    642      1.1  christos #ifdef NO_LEAKS
    643      1.1  christos void
    644      1.1  christos lalr_leaks(void)
    645      1.1  christos {
    646      1.1  christos     int i;
    647      1.1  christos 
    648      1.1  christos     if (includes != 0)
    649      1.1  christos     {
    650      1.1  christos 	for (i = 0; i < ngotos; i++)
    651      1.1  christos 	{
    652      1.1  christos 	    free(includes[i]);
    653      1.1  christos 	}
    654      1.1  christos 	DO_FREE(includes);
    655      1.1  christos     }
    656      1.1  christos }
    657      1.1  christos #endif
    658