Home | History | Annotate | Line # | Download | only in dist
lalr.c revision 1.1.1.5
      1  1.1.1.3  christos /*	$NetBSD: lalr.c,v 1.1.1.5 2015/01/03 22:58:23 christos Exp $	*/
      2  1.1.1.3  christos 
      3  1.1.1.5  christos /* Id: lalr.c,v 1.11 2014/09/18 00:26:39 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.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  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  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     Value_t state1;
    189      1.1  christos 
    190  1.1.1.5  christos     goto_base = NEW2(nvars + 1, Value_t);
    191  1.1.1.5  christos     temp_base = NEW2(nvars + 1, Value_t);
    192  1.1.1.5  christos 
    193  1.1.1.5  christos     goto_map = goto_base - ntokens;
    194  1.1.1.5  christos     temp_map = temp_base - ntokens;
    195      1.1  christos 
    196      1.1  christos     ngotos = 0;
    197      1.1  christos     for (sp = first_shift; sp; sp = sp->next)
    198      1.1  christos     {
    199      1.1  christos 	for (i = sp->nshifts - 1; i >= 0; i--)
    200      1.1  christos 	{
    201      1.1  christos 	    symbol = accessing_symbol[sp->shift[i]];
    202      1.1  christos 
    203      1.1  christos 	    if (ISTOKEN(symbol))
    204      1.1  christos 		break;
    205      1.1  christos 
    206  1.1.1.5  christos 	    if (ngotos == MAXYYINT)
    207      1.1  christos 		fatal("too many gotos");
    208      1.1  christos 
    209      1.1  christos 	    ngotos++;
    210      1.1  christos 	    goto_map[symbol]++;
    211      1.1  christos 	}
    212      1.1  christos     }
    213      1.1  christos 
    214      1.1  christos     k = 0;
    215      1.1  christos     for (i = ntokens; i < nsyms; i++)
    216      1.1  christos     {
    217      1.1  christos 	temp_map[i] = (Value_t) k;
    218      1.1  christos 	k += goto_map[i];
    219      1.1  christos     }
    220      1.1  christos 
    221      1.1  christos     for (i = ntokens; i < nsyms; i++)
    222      1.1  christos 	goto_map[i] = temp_map[i];
    223      1.1  christos 
    224      1.1  christos     goto_map[nsyms] = (Value_t) ngotos;
    225      1.1  christos     temp_map[nsyms] = (Value_t) ngotos;
    226      1.1  christos 
    227      1.1  christos     from_state = NEW2(ngotos, Value_t);
    228      1.1  christos     to_state = NEW2(ngotos, Value_t);
    229      1.1  christos 
    230      1.1  christos     for (sp = first_shift; sp; sp = sp->next)
    231      1.1  christos     {
    232      1.1  christos 	state1 = sp->number;
    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  christos     int high;
    256      1.1  christos     int low;
    257      1.1  christos     int middle;
    258      1.1  christos     int s;
    259      1.1  christos 
    260      1.1  christos     low = goto_map[symbol];
    261      1.1  christos     high = goto_map[symbol + 1];
    262      1.1  christos 
    263      1.1  christos     for (;;)
    264      1.1  christos     {
    265      1.1  christos 	assert(low <= high);
    266      1.1  christos 	middle = (low + high) >> 1;
    267      1.1  christos 	s = from_state[middle];
    268      1.1  christos 	if (s == state)
    269      1.1  christos 	    return (Value_t) (middle);
    270      1.1  christos 	else if (s < state)
    271      1.1  christos 	    low = middle + 1;
    272      1.1  christos 	else
    273      1.1  christos 	    high = middle - 1;
    274      1.1  christos     }
    275      1.1  christos }
    276      1.1  christos 
    277      1.1  christos static void
    278      1.1  christos initialize_F(void)
    279      1.1  christos {
    280      1.1  christos     int i;
    281      1.1  christos     int j;
    282      1.1  christos     int k;
    283      1.1  christos     shifts *sp;
    284      1.1  christos     Value_t *edge;
    285      1.1  christos     unsigned *rowp;
    286      1.1  christos     Value_t *rp;
    287      1.1  christos     Value_t **reads;
    288      1.1  christos     int nedges;
    289      1.1  christos     int stateno;
    290      1.1  christos     int symbol;
    291      1.1  christos     int nwords;
    292      1.1  christos 
    293      1.1  christos     nwords = ngotos * tokensetsize;
    294      1.1  christos     F = NEW2(nwords, unsigned);
    295      1.1  christos 
    296      1.1  christos     reads = NEW2(ngotos, Value_t *);
    297      1.1  christos     edge = NEW2(ngotos + 1, Value_t);
    298      1.1  christos     nedges = 0;
    299      1.1  christos 
    300      1.1  christos     rowp = F;
    301      1.1  christos     for (i = 0; i < ngotos; i++)
    302      1.1  christos     {
    303      1.1  christos 	stateno = to_state[i];
    304      1.1  christos 	sp = shift_table[stateno];
    305      1.1  christos 
    306      1.1  christos 	if (sp)
    307      1.1  christos 	{
    308      1.1  christos 	    k = sp->nshifts;
    309      1.1  christos 
    310      1.1  christos 	    for (j = 0; j < k; j++)
    311      1.1  christos 	    {
    312      1.1  christos 		symbol = accessing_symbol[sp->shift[j]];
    313      1.1  christos 		if (ISVAR(symbol))
    314      1.1  christos 		    break;
    315      1.1  christos 		SETBIT(rowp, symbol);
    316      1.1  christos 	    }
    317      1.1  christos 
    318      1.1  christos 	    for (; j < k; j++)
    319      1.1  christos 	    {
    320      1.1  christos 		symbol = accessing_symbol[sp->shift[j]];
    321      1.1  christos 		if (nullable[symbol])
    322      1.1  christos 		    edge[nedges++] = map_goto(stateno, symbol);
    323      1.1  christos 	    }
    324      1.1  christos 
    325      1.1  christos 	    if (nedges)
    326      1.1  christos 	    {
    327      1.1  christos 		reads[i] = rp = NEW2(nedges + 1, Value_t);
    328      1.1  christos 
    329      1.1  christos 		for (j = 0; j < nedges; j++)
    330      1.1  christos 		    rp[j] = edge[j];
    331      1.1  christos 
    332      1.1  christos 		rp[nedges] = -1;
    333      1.1  christos 		nedges = 0;
    334      1.1  christos 	    }
    335      1.1  christos 	}
    336      1.1  christos 
    337      1.1  christos 	rowp += tokensetsize;
    338      1.1  christos     }
    339      1.1  christos 
    340      1.1  christos     SETBIT(F, 0);
    341      1.1  christos     digraph(reads);
    342      1.1  christos 
    343      1.1  christos     for (i = 0; i < ngotos; i++)
    344      1.1  christos     {
    345      1.1  christos 	if (reads[i])
    346      1.1  christos 	    FREE(reads[i]);
    347      1.1  christos     }
    348      1.1  christos 
    349      1.1  christos     FREE(reads);
    350      1.1  christos     FREE(edge);
    351      1.1  christos }
    352      1.1  christos 
    353      1.1  christos static void
    354      1.1  christos build_relations(void)
    355      1.1  christos {
    356      1.1  christos     int i;
    357      1.1  christos     int j;
    358      1.1  christos     int k;
    359      1.1  christos     Value_t *rulep;
    360      1.1  christos     Value_t *rp;
    361      1.1  christos     shifts *sp;
    362      1.1  christos     int length;
    363      1.1  christos     int nedges;
    364      1.1  christos     int done_flag;
    365      1.1  christos     Value_t state1;
    366      1.1  christos     Value_t stateno;
    367      1.1  christos     int symbol1;
    368      1.1  christos     int symbol2;
    369      1.1  christos     Value_t *shortp;
    370      1.1  christos     Value_t *edge;
    371      1.1  christos     Value_t *states;
    372      1.1  christos     Value_t **new_includes;
    373      1.1  christos 
    374      1.1  christos     includes = NEW2(ngotos, Value_t *);
    375      1.1  christos     edge = NEW2(ngotos + 1, Value_t);
    376      1.1  christos     states = NEW2(maxrhs + 1, Value_t);
    377      1.1  christos 
    378      1.1  christos     for (i = 0; i < ngotos; i++)
    379      1.1  christos     {
    380      1.1  christos 	nedges = 0;
    381      1.1  christos 	state1 = from_state[i];
    382      1.1  christos 	symbol1 = accessing_symbol[to_state[i]];
    383      1.1  christos 
    384      1.1  christos 	for (rulep = derives[symbol1]; *rulep >= 0; rulep++)
    385      1.1  christos 	{
    386      1.1  christos 	    length = 1;
    387      1.1  christos 	    states[0] = state1;
    388      1.1  christos 	    stateno = state1;
    389      1.1  christos 
    390      1.1  christos 	    for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++)
    391      1.1  christos 	    {
    392      1.1  christos 		symbol2 = *rp;
    393      1.1  christos 		sp = shift_table[stateno];
    394      1.1  christos 		k = sp->nshifts;
    395      1.1  christos 
    396      1.1  christos 		for (j = 0; j < k; j++)
    397      1.1  christos 		{
    398      1.1  christos 		    stateno = sp->shift[j];
    399      1.1  christos 		    if (accessing_symbol[stateno] == symbol2)
    400      1.1  christos 			break;
    401      1.1  christos 		}
    402      1.1  christos 
    403      1.1  christos 		states[length++] = stateno;
    404      1.1  christos 	    }
    405      1.1  christos 
    406      1.1  christos 	    add_lookback_edge(stateno, *rulep, i);
    407      1.1  christos 
    408      1.1  christos 	    length--;
    409      1.1  christos 	    done_flag = 0;
    410      1.1  christos 	    while (!done_flag)
    411      1.1  christos 	    {
    412      1.1  christos 		done_flag = 1;
    413      1.1  christos 		rp--;
    414      1.1  christos 		if (ISVAR(*rp))
    415      1.1  christos 		{
    416      1.1  christos 		    stateno = states[--length];
    417      1.1  christos 		    edge[nedges++] = map_goto(stateno, *rp);
    418      1.1  christos 		    if (nullable[*rp] && length > 0)
    419      1.1  christos 			done_flag = 0;
    420      1.1  christos 		}
    421      1.1  christos 	    }
    422      1.1  christos 	}
    423      1.1  christos 
    424      1.1  christos 	if (nedges)
    425      1.1  christos 	{
    426      1.1  christos 	    includes[i] = shortp = NEW2(nedges + 1, Value_t);
    427      1.1  christos 	    for (j = 0; j < nedges; j++)
    428      1.1  christos 		shortp[j] = edge[j];
    429      1.1  christos 	    shortp[nedges] = -1;
    430      1.1  christos 	}
    431      1.1  christos     }
    432      1.1  christos 
    433      1.1  christos     new_includes = transpose(includes, ngotos);
    434      1.1  christos 
    435      1.1  christos     for (i = 0; i < ngotos; i++)
    436      1.1  christos 	if (includes[i])
    437      1.1  christos 	    FREE(includes[i]);
    438      1.1  christos 
    439      1.1  christos     FREE(includes);
    440      1.1  christos 
    441      1.1  christos     includes = new_includes;
    442      1.1  christos 
    443      1.1  christos     FREE(edge);
    444      1.1  christos     FREE(states);
    445      1.1  christos }
    446      1.1  christos 
    447      1.1  christos static void
    448      1.1  christos add_lookback_edge(int stateno, int ruleno, int gotono)
    449      1.1  christos {
    450      1.1  christos     int i, k;
    451      1.1  christos     int found;
    452      1.1  christos     shorts *sp;
    453      1.1  christos 
    454      1.1  christos     i = lookaheads[stateno];
    455      1.1  christos     k = lookaheads[stateno + 1];
    456      1.1  christos     found = 0;
    457      1.1  christos     while (!found && i < k)
    458      1.1  christos     {
    459      1.1  christos 	if (LAruleno[i] == ruleno)
    460      1.1  christos 	    found = 1;
    461      1.1  christos 	else
    462      1.1  christos 	    ++i;
    463      1.1  christos     }
    464      1.1  christos     assert(found);
    465      1.1  christos 
    466      1.1  christos     sp = NEW(shorts);
    467      1.1  christos     sp->next = lookback[i];
    468      1.1  christos     sp->value = (Value_t) gotono;
    469      1.1  christos     lookback[i] = sp;
    470      1.1  christos }
    471      1.1  christos 
    472      1.1  christos static Value_t **
    473      1.1  christos transpose(Value_t ** R2, int n)
    474      1.1  christos {
    475      1.1  christos     Value_t **new_R;
    476      1.1  christos     Value_t **temp_R;
    477      1.1  christos     Value_t *nedges;
    478      1.1  christos     Value_t *sp;
    479      1.1  christos     int i;
    480      1.1  christos     int k;
    481      1.1  christos 
    482      1.1  christos     nedges = NEW2(n, Value_t);
    483      1.1  christos 
    484      1.1  christos     for (i = 0; i < n; i++)
    485      1.1  christos     {
    486      1.1  christos 	sp = R2[i];
    487      1.1  christos 	if (sp)
    488      1.1  christos 	{
    489      1.1  christos 	    while (*sp >= 0)
    490      1.1  christos 		nedges[*sp++]++;
    491      1.1  christos 	}
    492      1.1  christos     }
    493      1.1  christos 
    494      1.1  christos     new_R = NEW2(n, Value_t *);
    495      1.1  christos     temp_R = NEW2(n, Value_t *);
    496      1.1  christos 
    497      1.1  christos     for (i = 0; i < n; i++)
    498      1.1  christos     {
    499      1.1  christos 	k = nedges[i];
    500      1.1  christos 	if (k > 0)
    501      1.1  christos 	{
    502      1.1  christos 	    sp = NEW2(k + 1, Value_t);
    503      1.1  christos 	    new_R[i] = sp;
    504      1.1  christos 	    temp_R[i] = sp;
    505      1.1  christos 	    sp[k] = -1;
    506      1.1  christos 	}
    507      1.1  christos     }
    508      1.1  christos 
    509      1.1  christos     FREE(nedges);
    510      1.1  christos 
    511      1.1  christos     for (i = 0; i < n; i++)
    512      1.1  christos     {
    513      1.1  christos 	sp = R2[i];
    514      1.1  christos 	if (sp)
    515      1.1  christos 	{
    516      1.1  christos 	    while (*sp >= 0)
    517      1.1  christos 		*temp_R[*sp++]++ = (Value_t) i;
    518      1.1  christos 	}
    519      1.1  christos     }
    520      1.1  christos 
    521      1.1  christos     FREE(temp_R);
    522      1.1  christos 
    523      1.1  christos     return (new_R);
    524      1.1  christos }
    525      1.1  christos 
    526      1.1  christos static void
    527      1.1  christos compute_FOLLOWS(void)
    528      1.1  christos {
    529      1.1  christos     digraph(includes);
    530      1.1  christos }
    531      1.1  christos 
    532      1.1  christos static void
    533      1.1  christos compute_lookaheads(void)
    534      1.1  christos {
    535      1.1  christos     int i, n;
    536      1.1  christos     unsigned *fp1, *fp2, *fp3;
    537      1.1  christos     shorts *sp, *next;
    538      1.1  christos     unsigned *rowp;
    539      1.1  christos 
    540      1.1  christos     rowp = LA;
    541      1.1  christos     n = lookaheads[nstates];
    542      1.1  christos     for (i = 0; i < n; i++)
    543      1.1  christos     {
    544      1.1  christos 	fp3 = rowp + tokensetsize;
    545      1.1  christos 	for (sp = lookback[i]; sp; sp = sp->next)
    546      1.1  christos 	{
    547      1.1  christos 	    fp1 = rowp;
    548      1.1  christos 	    fp2 = F + tokensetsize * sp->value;
    549      1.1  christos 	    while (fp1 < fp3)
    550      1.1  christos 		*fp1++ |= *fp2++;
    551      1.1  christos 	}
    552      1.1  christos 	rowp = fp3;
    553      1.1  christos     }
    554      1.1  christos 
    555      1.1  christos     for (i = 0; i < n; i++)
    556      1.1  christos 	for (sp = lookback[i]; sp; sp = next)
    557      1.1  christos 	{
    558      1.1  christos 	    next = sp->next;
    559      1.1  christos 	    FREE(sp);
    560      1.1  christos 	}
    561      1.1  christos 
    562      1.1  christos     FREE(lookback);
    563      1.1  christos     FREE(F);
    564      1.1  christos }
    565      1.1  christos 
    566      1.1  christos static void
    567      1.1  christos digraph(Value_t ** relation)
    568      1.1  christos {
    569      1.1  christos     int i;
    570      1.1  christos 
    571      1.1  christos     infinity = (Value_t) (ngotos + 2);
    572      1.1  christos     INDEX = NEW2(ngotos + 1, Value_t);
    573      1.1  christos     VERTICES = NEW2(ngotos + 1, Value_t);
    574      1.1  christos     top = 0;
    575      1.1  christos 
    576      1.1  christos     R = relation;
    577      1.1  christos 
    578      1.1  christos     for (i = 0; i < ngotos; i++)
    579      1.1  christos 	INDEX[i] = 0;
    580      1.1  christos 
    581      1.1  christos     for (i = 0; i < ngotos; i++)
    582      1.1  christos     {
    583      1.1  christos 	if (INDEX[i] == 0 && R[i])
    584      1.1  christos 	    traverse(i);
    585      1.1  christos     }
    586      1.1  christos 
    587      1.1  christos     FREE(INDEX);
    588      1.1  christos     FREE(VERTICES);
    589      1.1  christos }
    590      1.1  christos 
    591      1.1  christos static void
    592      1.1  christos traverse(int i)
    593      1.1  christos {
    594      1.1  christos     unsigned *fp1;
    595      1.1  christos     unsigned *fp2;
    596      1.1  christos     unsigned *fp3;
    597      1.1  christos     int j;
    598      1.1  christos     Value_t *rp;
    599      1.1  christos 
    600      1.1  christos     Value_t height;
    601      1.1  christos     unsigned *base;
    602      1.1  christos 
    603      1.1  christos     VERTICES[++top] = (Value_t) i;
    604      1.1  christos     INDEX[i] = height = top;
    605      1.1  christos 
    606      1.1  christos     base = F + i * tokensetsize;
    607      1.1  christos     fp3 = base + tokensetsize;
    608      1.1  christos 
    609      1.1  christos     rp = R[i];
    610      1.1  christos     if (rp)
    611      1.1  christos     {
    612      1.1  christos 	while ((j = *rp++) >= 0)
    613      1.1  christos 	{
    614      1.1  christos 	    if (INDEX[j] == 0)
    615      1.1  christos 		traverse(j);
    616      1.1  christos 
    617      1.1  christos 	    if (INDEX[i] > INDEX[j])
    618      1.1  christos 		INDEX[i] = INDEX[j];
    619      1.1  christos 
    620      1.1  christos 	    fp1 = base;
    621      1.1  christos 	    fp2 = F + j * tokensetsize;
    622      1.1  christos 
    623      1.1  christos 	    while (fp1 < fp3)
    624      1.1  christos 		*fp1++ |= *fp2++;
    625      1.1  christos 	}
    626      1.1  christos     }
    627      1.1  christos 
    628      1.1  christos     if (INDEX[i] == height)
    629      1.1  christos     {
    630      1.1  christos 	for (;;)
    631      1.1  christos 	{
    632      1.1  christos 	    j = VERTICES[top--];
    633      1.1  christos 	    INDEX[j] = infinity;
    634      1.1  christos 
    635      1.1  christos 	    if (i == j)
    636      1.1  christos 		break;
    637      1.1  christos 
    638      1.1  christos 	    fp1 = base;
    639      1.1  christos 	    fp2 = F + j * tokensetsize;
    640      1.1  christos 
    641      1.1  christos 	    while (fp1 < fp3)
    642      1.1  christos 		*fp2++ = *fp1++;
    643      1.1  christos 	}
    644      1.1  christos     }
    645      1.1  christos }
    646      1.1  christos 
    647      1.1  christos #ifdef NO_LEAKS
    648      1.1  christos void
    649      1.1  christos lalr_leaks(void)
    650      1.1  christos {
    651      1.1  christos     int i;
    652      1.1  christos 
    653      1.1  christos     if (includes != 0)
    654      1.1  christos     {
    655      1.1  christos 	for (i = 0; i < ngotos; i++)
    656      1.1  christos 	{
    657      1.1  christos 	    free(includes[i]);
    658      1.1  christos 	}
    659      1.1  christos 	DO_FREE(includes);
    660      1.1  christos     }
    661      1.1  christos }
    662      1.1  christos #endif
    663