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