Home | History | Annotate | Line # | Download | only in dist
lalr.c revision 1.1.1.9
      1  1.1.1.7  christos /*	$NetBSD: lalr.c,v 1.1.1.9 2021/02/20 20:30:07 christos Exp $	*/
      2  1.1.1.7  christos 
      3  1.1.1.9  christos /* Id: lalr.c,v 1.13 2020/09/10 17:26:21 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.1.8  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.1.8  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.1.5  christos Value_t *goto_base;
     40      1.1  christos Value_t *goto_map;
     41      1.1  christos Value_t *from_state;
     42      1.1  christos Value_t *to_state;
     43      1.1  christos 
     44      1.1  christos static Value_t infinity;
     45      1.1  christos static int maxrhs;
     46      1.1  christos static int ngotos;
     47      1.1  christos static unsigned *F;
     48      1.1  christos static Value_t **includes;
     49      1.1  christos static shorts **lookback;
     50      1.1  christos static Value_t **R;
     51      1.1  christos static Value_t *INDEX;
     52      1.1  christos static Value_t *VERTICES;
     53      1.1  christos static Value_t top;
     54      1.1  christos 
     55      1.1  christos void
     56      1.1  christos lalr(void)
     57      1.1  christos {
     58      1.1  christos     tokensetsize = WORDSIZE(ntokens);
     59      1.1  christos 
     60      1.1  christos     set_state_table();
     61      1.1  christos     set_accessing_symbol();
     62      1.1  christos     set_shift_table();
     63      1.1  christos     set_reduction_table();
     64      1.1  christos     set_maxrhs();
     65      1.1  christos     initialize_LA();
     66      1.1  christos     set_goto_map();
     67      1.1  christos     initialize_F();
     68      1.1  christos     build_relations();
     69      1.1  christos     compute_FOLLOWS();
     70      1.1  christos     compute_lookaheads();
     71      1.1  christos }
     72      1.1  christos 
     73      1.1  christos static void
     74      1.1  christos set_state_table(void)
     75      1.1  christos {
     76      1.1  christos     core *sp;
     77      1.1  christos 
     78      1.1  christos     state_table = NEW2(nstates, core *);
     79      1.1  christos     for (sp = first_state; sp; sp = sp->next)
     80      1.1  christos 	state_table[sp->number] = sp;
     81      1.1  christos }
     82      1.1  christos 
     83      1.1  christos static void
     84      1.1  christos set_accessing_symbol(void)
     85      1.1  christos {
     86      1.1  christos     core *sp;
     87      1.1  christos 
     88      1.1  christos     accessing_symbol = NEW2(nstates, Value_t);
     89      1.1  christos     for (sp = first_state; sp; sp = sp->next)
     90      1.1  christos 	accessing_symbol[sp->number] = sp->accessing_symbol;
     91      1.1  christos }
     92      1.1  christos 
     93      1.1  christos static void
     94      1.1  christos set_shift_table(void)
     95      1.1  christos {
     96      1.1  christos     shifts *sp;
     97      1.1  christos 
     98      1.1  christos     shift_table = NEW2(nstates, shifts *);
     99      1.1  christos     for (sp = first_shift; sp; sp = sp->next)
    100      1.1  christos 	shift_table[sp->number] = sp;
    101      1.1  christos }
    102      1.1  christos 
    103      1.1  christos static void
    104      1.1  christos set_reduction_table(void)
    105      1.1  christos {
    106      1.1  christos     reductions *rp;
    107      1.1  christos 
    108      1.1  christos     reduction_table = NEW2(nstates, reductions *);
    109      1.1  christos     for (rp = first_reduction; rp; rp = rp->next)
    110      1.1  christos 	reduction_table[rp->number] = rp;
    111      1.1  christos }
    112      1.1  christos 
    113      1.1  christos static void
    114      1.1  christos set_maxrhs(void)
    115      1.1  christos {
    116      1.1  christos     Value_t *itemp;
    117      1.1  christos     Value_t *item_end;
    118      1.1  christos     int length;
    119      1.1  christos     int max;
    120      1.1  christos 
    121      1.1  christos     length = 0;
    122      1.1  christos     max = 0;
    123      1.1  christos     item_end = ritem + nitems;
    124      1.1  christos     for (itemp = ritem; itemp < item_end; itemp++)
    125      1.1  christos     {
    126      1.1  christos 	if (*itemp >= 0)
    127      1.1  christos 	{
    128      1.1  christos 	    length++;
    129      1.1  christos 	}
    130      1.1  christos 	else
    131      1.1  christos 	{
    132      1.1  christos 	    if (length > max)
    133      1.1  christos 		max = length;
    134      1.1  christos 	    length = 0;
    135      1.1  christos 	}
    136      1.1  christos     }
    137      1.1  christos 
    138      1.1  christos     maxrhs = max;
    139      1.1  christos }
    140      1.1  christos 
    141      1.1  christos static void
    142      1.1  christos initialize_LA(void)
    143      1.1  christos {
    144      1.1  christos     int i, j, k;
    145      1.1  christos     reductions *rp;
    146      1.1  christos 
    147      1.1  christos     lookaheads = NEW2(nstates + 1, Value_t);
    148      1.1  christos 
    149      1.1  christos     k = 0;
    150      1.1  christos     for (i = 0; i < nstates; i++)
    151      1.1  christos     {
    152  1.1.1.8  christos 	lookaheads[i] = (Value_t)k;
    153      1.1  christos 	rp = reduction_table[i];
    154      1.1  christos 	if (rp)
    155      1.1  christos 	    k += rp->nreds;
    156      1.1  christos     }
    157  1.1.1.8  christos     lookaheads[nstates] = (Value_t)k;
    158      1.1  christos 
    159      1.1  christos     LA = NEW2(k * tokensetsize, unsigned);
    160      1.1  christos     LAruleno = NEW2(k, Value_t);
    161      1.1  christos     lookback = NEW2(k, shorts *);
    162      1.1  christos 
    163      1.1  christos     k = 0;
    164      1.1  christos     for (i = 0; i < nstates; i++)
    165      1.1  christos     {
    166      1.1  christos 	rp = reduction_table[i];
    167      1.1  christos 	if (rp)
    168      1.1  christos 	{
    169      1.1  christos 	    for (j = 0; j < rp->nreds; j++)
    170      1.1  christos 	    {
    171      1.1  christos 		LAruleno[k] = rp->rules[j];
    172      1.1  christos 		k++;
    173      1.1  christos 	    }
    174      1.1  christos 	}
    175      1.1  christos     }
    176      1.1  christos }
    177      1.1  christos 
    178      1.1  christos static void
    179      1.1  christos set_goto_map(void)
    180      1.1  christos {
    181      1.1  christos     shifts *sp;
    182      1.1  christos     int i;
    183      1.1  christos     int symbol;
    184      1.1  christos     int k;
    185  1.1.1.5  christos     Value_t *temp_base;
    186      1.1  christos     Value_t *temp_map;
    187      1.1  christos     Value_t state2;
    188      1.1  christos 
    189  1.1.1.5  christos     goto_base = NEW2(nvars + 1, Value_t);
    190  1.1.1.5  christos     temp_base = NEW2(nvars + 1, Value_t);
    191  1.1.1.5  christos 
    192  1.1.1.5  christos     goto_map = goto_base - ntokens;
    193  1.1.1.5  christos     temp_map = temp_base - ntokens;
    194      1.1  christos 
    195      1.1  christos     ngotos = 0;
    196      1.1  christos     for (sp = first_shift; sp; sp = sp->next)
    197      1.1  christos     {
    198      1.1  christos 	for (i = sp->nshifts - 1; i >= 0; i--)
    199      1.1  christos 	{
    200      1.1  christos 	    symbol = accessing_symbol[sp->shift[i]];
    201      1.1  christos 
    202      1.1  christos 	    if (ISTOKEN(symbol))
    203      1.1  christos 		break;
    204      1.1  christos 
    205  1.1.1.5  christos 	    if (ngotos == MAXYYINT)
    206      1.1  christos 		fatal("too many gotos");
    207      1.1  christos 
    208      1.1  christos 	    ngotos++;
    209      1.1  christos 	    goto_map[symbol]++;
    210      1.1  christos 	}
    211      1.1  christos     }
    212      1.1  christos 
    213      1.1  christos     k = 0;
    214      1.1  christos     for (i = ntokens; i < nsyms; i++)
    215      1.1  christos     {
    216  1.1.1.8  christos 	temp_map[i] = (Value_t)k;
    217      1.1  christos 	k += goto_map[i];
    218      1.1  christos     }
    219      1.1  christos 
    220      1.1  christos     for (i = ntokens; i < nsyms; i++)
    221      1.1  christos 	goto_map[i] = temp_map[i];
    222      1.1  christos 
    223  1.1.1.8  christos     goto_map[nsyms] = (Value_t)ngotos;
    224  1.1.1.8  christos     temp_map[nsyms] = (Value_t)ngotos;
    225      1.1  christos 
    226      1.1  christos     from_state = NEW2(ngotos, Value_t);
    227      1.1  christos     to_state = NEW2(ngotos, Value_t);
    228      1.1  christos 
    229      1.1  christos     for (sp = first_shift; sp; sp = sp->next)
    230      1.1  christos     {
    231  1.1.1.9  christos 	Value_t state1 = sp->number;
    232  1.1.1.9  christos 
    233      1.1  christos 	for (i = sp->nshifts - 1; i >= 0; i--)
    234      1.1  christos 	{
    235      1.1  christos 	    state2 = sp->shift[i];
    236      1.1  christos 	    symbol = accessing_symbol[state2];
    237      1.1  christos 
    238      1.1  christos 	    if (ISTOKEN(symbol))
    239      1.1  christos 		break;
    240      1.1  christos 
    241      1.1  christos 	    k = temp_map[symbol]++;
    242      1.1  christos 	    from_state[k] = state1;
    243      1.1  christos 	    to_state[k] = state2;
    244      1.1  christos 	}
    245      1.1  christos     }
    246      1.1  christos 
    247  1.1.1.5  christos     FREE(temp_base);
    248      1.1  christos }
    249      1.1  christos 
    250      1.1  christos /*  Map_goto maps a state/symbol pair into its numeric representation.	*/
    251      1.1  christos 
    252      1.1  christos static Value_t
    253      1.1  christos map_goto(int state, int symbol)
    254      1.1  christos {
    255  1.1.1.9  christos     int low = goto_map[symbol];
    256  1.1.1.9  christos     int high = goto_map[symbol + 1];
    257      1.1  christos 
    258      1.1  christos     for (;;)
    259      1.1  christos     {
    260  1.1.1.9  christos 	int middle;
    261  1.1.1.9  christos 	int s;
    262  1.1.1.9  christos 
    263      1.1  christos 	assert(low <= high);
    264      1.1  christos 	middle = (low + high) >> 1;
    265      1.1  christos 	s = from_state[middle];
    266      1.1  christos 	if (s == state)
    267  1.1.1.8  christos 	    return (Value_t)(middle);
    268      1.1  christos 	else if (s < state)
    269      1.1  christos 	    low = middle + 1;
    270      1.1  christos 	else
    271      1.1  christos 	    high = middle - 1;
    272      1.1  christos     }
    273      1.1  christos }
    274      1.1  christos 
    275      1.1  christos static void
    276      1.1  christos initialize_F(void)
    277      1.1  christos {
    278      1.1  christos     int i;
    279      1.1  christos     int j;
    280      1.1  christos     int k;
    281      1.1  christos     shifts *sp;
    282      1.1  christos     Value_t *edge;
    283      1.1  christos     unsigned *rowp;
    284      1.1  christos     Value_t *rp;
    285      1.1  christos     Value_t **reads;
    286      1.1  christos     int nedges;
    287      1.1  christos     int symbol;
    288      1.1  christos     int nwords;
    289      1.1  christos 
    290      1.1  christos     nwords = ngotos * tokensetsize;
    291      1.1  christos     F = NEW2(nwords, unsigned);
    292      1.1  christos 
    293      1.1  christos     reads = NEW2(ngotos, Value_t *);
    294      1.1  christos     edge = NEW2(ngotos + 1, Value_t);
    295      1.1  christos     nedges = 0;
    296      1.1  christos 
    297      1.1  christos     rowp = F;
    298      1.1  christos     for (i = 0; i < ngotos; i++)
    299      1.1  christos     {
    300  1.1.1.9  christos 	int stateno = to_state[i];
    301  1.1.1.9  christos 
    302      1.1  christos 	sp = shift_table[stateno];
    303      1.1  christos 
    304      1.1  christos 	if (sp)
    305      1.1  christos 	{
    306      1.1  christos 	    k = sp->nshifts;
    307      1.1  christos 
    308      1.1  christos 	    for (j = 0; j < k; j++)
    309      1.1  christos 	    {
    310      1.1  christos 		symbol = accessing_symbol[sp->shift[j]];
    311      1.1  christos 		if (ISVAR(symbol))
    312      1.1  christos 		    break;
    313      1.1  christos 		SETBIT(rowp, symbol);
    314      1.1  christos 	    }
    315      1.1  christos 
    316      1.1  christos 	    for (; j < k; j++)
    317      1.1  christos 	    {
    318      1.1  christos 		symbol = accessing_symbol[sp->shift[j]];
    319      1.1  christos 		if (nullable[symbol])
    320      1.1  christos 		    edge[nedges++] = map_goto(stateno, symbol);
    321      1.1  christos 	    }
    322      1.1  christos 
    323      1.1  christos 	    if (nedges)
    324      1.1  christos 	    {
    325      1.1  christos 		reads[i] = rp = NEW2(nedges + 1, Value_t);
    326      1.1  christos 
    327      1.1  christos 		for (j = 0; j < nedges; j++)
    328      1.1  christos 		    rp[j] = edge[j];
    329      1.1  christos 
    330      1.1  christos 		rp[nedges] = -1;
    331      1.1  christos 		nedges = 0;
    332      1.1  christos 	    }
    333      1.1  christos 	}
    334      1.1  christos 
    335      1.1  christos 	rowp += tokensetsize;
    336      1.1  christos     }
    337      1.1  christos 
    338      1.1  christos     SETBIT(F, 0);
    339      1.1  christos     digraph(reads);
    340      1.1  christos 
    341      1.1  christos     for (i = 0; i < ngotos; i++)
    342      1.1  christos     {
    343      1.1  christos 	if (reads[i])
    344      1.1  christos 	    FREE(reads[i]);
    345      1.1  christos     }
    346      1.1  christos 
    347      1.1  christos     FREE(reads);
    348      1.1  christos     FREE(edge);
    349      1.1  christos }
    350      1.1  christos 
    351      1.1  christos static void
    352      1.1  christos build_relations(void)
    353      1.1  christos {
    354      1.1  christos     int i;
    355      1.1  christos     int j;
    356      1.1  christos     int k;
    357      1.1  christos     Value_t *rulep;
    358      1.1  christos     Value_t *rp;
    359      1.1  christos     shifts *sp;
    360      1.1  christos     int length;
    361      1.1  christos     int done_flag;
    362      1.1  christos     Value_t stateno;
    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.1.9  christos 	int nedges = 0;
    376  1.1.1.9  christos 	int symbol1 = accessing_symbol[to_state[i]];
    377  1.1.1.9  christos 	Value_t state1 = from_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.1.8  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.1.8  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 
    476      1.1  christos     nedges = NEW2(n, Value_t);
    477      1.1  christos 
    478      1.1  christos     for (i = 0; i < n; i++)
    479      1.1  christos     {
    480      1.1  christos 	sp = R2[i];
    481      1.1  christos 	if (sp)
    482      1.1  christos 	{
    483      1.1  christos 	    while (*sp >= 0)
    484      1.1  christos 		nedges[*sp++]++;
    485      1.1  christos 	}
    486      1.1  christos     }
    487      1.1  christos 
    488      1.1  christos     new_R = NEW2(n, Value_t *);
    489      1.1  christos     temp_R = NEW2(n, Value_t *);
    490      1.1  christos 
    491      1.1  christos     for (i = 0; i < n; i++)
    492      1.1  christos     {
    493  1.1.1.9  christos 	int k = nedges[i];
    494  1.1.1.9  christos 
    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.1.8  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.1.8  christos digraph(Value_t **relation)
    563      1.1  christos {
    564      1.1  christos     int i;
    565      1.1  christos 
    566  1.1.1.8  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.1.8  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     if (includes != 0)
    647      1.1  christos     {
    648  1.1.1.9  christos 	int i;
    649  1.1.1.9  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