1319297Sdelphij/* $Id: lalr.c,v 1.12 2016/06/07 00:28:03 tom Exp $ */
2234949Sbapt
3234949Sbapt#include "defs.h"
4234949Sbapt
5234949Sbapttypedef struct shorts
6234949Sbapt{
7234949Sbapt    struct shorts *next;
8234949Sbapt    Value_t value;
9234949Sbapt}
10234949Sbaptshorts;
11234949Sbapt
12234949Sbaptstatic Value_t map_goto(int state, int symbol);
13319297Sdelphijstatic Value_t **transpose(Value_t **R, int n);
14234949Sbaptstatic void add_lookback_edge(int stateno, int ruleno, int gotono);
15234949Sbaptstatic void build_relations(void);
16234949Sbaptstatic void compute_FOLLOWS(void);
17234949Sbaptstatic void compute_lookaheads(void);
18319297Sdelphijstatic void digraph(Value_t **relation);
19234949Sbaptstatic void initialize_F(void);
20234949Sbaptstatic void initialize_LA(void);
21234949Sbaptstatic void set_accessing_symbol(void);
22234949Sbaptstatic void set_goto_map(void);
23234949Sbaptstatic void set_maxrhs(void);
24234949Sbaptstatic void set_reduction_table(void);
25234949Sbaptstatic void set_shift_table(void);
26234949Sbaptstatic void set_state_table(void);
27234949Sbaptstatic void traverse(int i);
28234949Sbapt
29234949Sbaptstatic int tokensetsize;
30234949SbaptValue_t *lookaheads;
31234949SbaptValue_t *LAruleno;
32234949Sbaptunsigned *LA;
33234949SbaptValue_t *accessing_symbol;
34234949Sbaptcore **state_table;
35234949Sbaptshifts **shift_table;
36234949Sbaptreductions **reduction_table;
37272655SbaptValue_t *goto_base;
38234949SbaptValue_t *goto_map;
39234949SbaptValue_t *from_state;
40234949SbaptValue_t *to_state;
41234949Sbapt
42234949Sbaptstatic Value_t infinity;
43234949Sbaptstatic int maxrhs;
44234949Sbaptstatic int ngotos;
45234949Sbaptstatic unsigned *F;
46234949Sbaptstatic Value_t **includes;
47234949Sbaptstatic shorts **lookback;
48234949Sbaptstatic Value_t **R;
49234949Sbaptstatic Value_t *INDEX;
50234949Sbaptstatic Value_t *VERTICES;
51234949Sbaptstatic Value_t top;
52234949Sbapt
53234949Sbaptvoid
54234949Sbaptlalr(void)
55234949Sbapt{
56234949Sbapt    tokensetsize = WORDSIZE(ntokens);
57234949Sbapt
58234949Sbapt    set_state_table();
59234949Sbapt    set_accessing_symbol();
60234949Sbapt    set_shift_table();
61234949Sbapt    set_reduction_table();
62234949Sbapt    set_maxrhs();
63234949Sbapt    initialize_LA();
64234949Sbapt    set_goto_map();
65234949Sbapt    initialize_F();
66234949Sbapt    build_relations();
67234949Sbapt    compute_FOLLOWS();
68234949Sbapt    compute_lookaheads();
69234949Sbapt}
70234949Sbapt
71234949Sbaptstatic void
72234949Sbaptset_state_table(void)
73234949Sbapt{
74234949Sbapt    core *sp;
75234949Sbapt
76234949Sbapt    state_table = NEW2(nstates, core *);
77234949Sbapt    for (sp = first_state; sp; sp = sp->next)
78234949Sbapt	state_table[sp->number] = sp;
79234949Sbapt}
80234949Sbapt
81234949Sbaptstatic void
82234949Sbaptset_accessing_symbol(void)
83234949Sbapt{
84234949Sbapt    core *sp;
85234949Sbapt
86234949Sbapt    accessing_symbol = NEW2(nstates, Value_t);
87234949Sbapt    for (sp = first_state; sp; sp = sp->next)
88234949Sbapt	accessing_symbol[sp->number] = sp->accessing_symbol;
89234949Sbapt}
90234949Sbapt
91234949Sbaptstatic void
92234949Sbaptset_shift_table(void)
93234949Sbapt{
94234949Sbapt    shifts *sp;
95234949Sbapt
96234949Sbapt    shift_table = NEW2(nstates, shifts *);
97234949Sbapt    for (sp = first_shift; sp; sp = sp->next)
98234949Sbapt	shift_table[sp->number] = sp;
99234949Sbapt}
100234949Sbapt
101234949Sbaptstatic void
102234949Sbaptset_reduction_table(void)
103234949Sbapt{
104234949Sbapt    reductions *rp;
105234949Sbapt
106234949Sbapt    reduction_table = NEW2(nstates, reductions *);
107234949Sbapt    for (rp = first_reduction; rp; rp = rp->next)
108234949Sbapt	reduction_table[rp->number] = rp;
109234949Sbapt}
110234949Sbapt
111234949Sbaptstatic void
112234949Sbaptset_maxrhs(void)
113234949Sbapt{
114234949Sbapt    Value_t *itemp;
115234949Sbapt    Value_t *item_end;
116234949Sbapt    int length;
117234949Sbapt    int max;
118234949Sbapt
119234949Sbapt    length = 0;
120234949Sbapt    max = 0;
121234949Sbapt    item_end = ritem + nitems;
122234949Sbapt    for (itemp = ritem; itemp < item_end; itemp++)
123234949Sbapt    {
124234949Sbapt	if (*itemp >= 0)
125234949Sbapt	{
126234949Sbapt	    length++;
127234949Sbapt	}
128234949Sbapt	else
129234949Sbapt	{
130234949Sbapt	    if (length > max)
131234949Sbapt		max = length;
132234949Sbapt	    length = 0;
133234949Sbapt	}
134234949Sbapt    }
135234949Sbapt
136234949Sbapt    maxrhs = max;
137234949Sbapt}
138234949Sbapt
139234949Sbaptstatic void
140234949Sbaptinitialize_LA(void)
141234949Sbapt{
142234949Sbapt    int i, j, k;
143234949Sbapt    reductions *rp;
144234949Sbapt
145234949Sbapt    lookaheads = NEW2(nstates + 1, Value_t);
146234949Sbapt
147234949Sbapt    k = 0;
148234949Sbapt    for (i = 0; i < nstates; i++)
149234949Sbapt    {
150319297Sdelphij	lookaheads[i] = (Value_t)k;
151234949Sbapt	rp = reduction_table[i];
152234949Sbapt	if (rp)
153234949Sbapt	    k += rp->nreds;
154234949Sbapt    }
155319297Sdelphij    lookaheads[nstates] = (Value_t)k;
156234949Sbapt
157234949Sbapt    LA = NEW2(k * tokensetsize, unsigned);
158234949Sbapt    LAruleno = NEW2(k, Value_t);
159234949Sbapt    lookback = NEW2(k, shorts *);
160234949Sbapt
161234949Sbapt    k = 0;
162234949Sbapt    for (i = 0; i < nstates; i++)
163234949Sbapt    {
164234949Sbapt	rp = reduction_table[i];
165234949Sbapt	if (rp)
166234949Sbapt	{
167234949Sbapt	    for (j = 0; j < rp->nreds; j++)
168234949Sbapt	    {
169234949Sbapt		LAruleno[k] = rp->rules[j];
170234949Sbapt		k++;
171234949Sbapt	    }
172234949Sbapt	}
173234949Sbapt    }
174234949Sbapt}
175234949Sbapt
176234949Sbaptstatic void
177234949Sbaptset_goto_map(void)
178234949Sbapt{
179234949Sbapt    shifts *sp;
180234949Sbapt    int i;
181234949Sbapt    int symbol;
182234949Sbapt    int k;
183272655Sbapt    Value_t *temp_base;
184234949Sbapt    Value_t *temp_map;
185234949Sbapt    Value_t state2;
186234949Sbapt    Value_t state1;
187234949Sbapt
188272655Sbapt    goto_base = NEW2(nvars + 1, Value_t);
189272655Sbapt    temp_base = NEW2(nvars + 1, Value_t);
190234949Sbapt
191272655Sbapt    goto_map = goto_base - ntokens;
192272655Sbapt    temp_map = temp_base - ntokens;
193272655Sbapt
194234949Sbapt    ngotos = 0;
195234949Sbapt    for (sp = first_shift; sp; sp = sp->next)
196234949Sbapt    {
197234949Sbapt	for (i = sp->nshifts - 1; i >= 0; i--)
198234949Sbapt	{
199234949Sbapt	    symbol = accessing_symbol[sp->shift[i]];
200234949Sbapt
201234949Sbapt	    if (ISTOKEN(symbol))
202234949Sbapt		break;
203234949Sbapt
204264803Sbapt	    if (ngotos == MAXYYINT)
205234949Sbapt		fatal("too many gotos");
206234949Sbapt
207234949Sbapt	    ngotos++;
208234949Sbapt	    goto_map[symbol]++;
209234949Sbapt	}
210234949Sbapt    }
211234949Sbapt
212234949Sbapt    k = 0;
213234949Sbapt    for (i = ntokens; i < nsyms; i++)
214234949Sbapt    {
215319297Sdelphij	temp_map[i] = (Value_t)k;
216234949Sbapt	k += goto_map[i];
217234949Sbapt    }
218234949Sbapt
219234949Sbapt    for (i = ntokens; i < nsyms; i++)
220234949Sbapt	goto_map[i] = temp_map[i];
221234949Sbapt
222319297Sdelphij    goto_map[nsyms] = (Value_t)ngotos;
223319297Sdelphij    temp_map[nsyms] = (Value_t)ngotos;
224234949Sbapt
225234949Sbapt    from_state = NEW2(ngotos, Value_t);
226234949Sbapt    to_state = NEW2(ngotos, Value_t);
227234949Sbapt
228234949Sbapt    for (sp = first_shift; sp; sp = sp->next)
229234949Sbapt    {
230234949Sbapt	state1 = sp->number;
231234949Sbapt	for (i = sp->nshifts - 1; i >= 0; i--)
232234949Sbapt	{
233234949Sbapt	    state2 = sp->shift[i];
234234949Sbapt	    symbol = accessing_symbol[state2];
235234949Sbapt
236234949Sbapt	    if (ISTOKEN(symbol))
237234949Sbapt		break;
238234949Sbapt
239234949Sbapt	    k = temp_map[symbol]++;
240234949Sbapt	    from_state[k] = state1;
241234949Sbapt	    to_state[k] = state2;
242234949Sbapt	}
243234949Sbapt    }
244234949Sbapt
245272655Sbapt    FREE(temp_base);
246234949Sbapt}
247234949Sbapt
248234949Sbapt/*  Map_goto maps a state/symbol pair into its numeric representation.	*/
249234949Sbapt
250234949Sbaptstatic Value_t
251234949Sbaptmap_goto(int state, int symbol)
252234949Sbapt{
253234949Sbapt    int high;
254234949Sbapt    int low;
255234949Sbapt    int middle;
256234949Sbapt    int s;
257234949Sbapt
258234949Sbapt    low = goto_map[symbol];
259234949Sbapt    high = goto_map[symbol + 1];
260234949Sbapt
261234949Sbapt    for (;;)
262234949Sbapt    {
263234949Sbapt	assert(low <= high);
264234949Sbapt	middle = (low + high) >> 1;
265234949Sbapt	s = from_state[middle];
266234949Sbapt	if (s == state)
267319297Sdelphij	    return (Value_t)(middle);
268234949Sbapt	else if (s < state)
269234949Sbapt	    low = middle + 1;
270234949Sbapt	else
271234949Sbapt	    high = middle - 1;
272234949Sbapt    }
273234949Sbapt}
274234949Sbapt
275234949Sbaptstatic void
276234949Sbaptinitialize_F(void)
277234949Sbapt{
278234949Sbapt    int i;
279234949Sbapt    int j;
280234949Sbapt    int k;
281234949Sbapt    shifts *sp;
282234949Sbapt    Value_t *edge;
283234949Sbapt    unsigned *rowp;
284234949Sbapt    Value_t *rp;
285234949Sbapt    Value_t **reads;
286234949Sbapt    int nedges;
287234949Sbapt    int stateno;
288234949Sbapt    int symbol;
289234949Sbapt    int nwords;
290234949Sbapt
291234949Sbapt    nwords = ngotos * tokensetsize;
292234949Sbapt    F = NEW2(nwords, unsigned);
293234949Sbapt
294234949Sbapt    reads = NEW2(ngotos, Value_t *);
295234949Sbapt    edge = NEW2(ngotos + 1, Value_t);
296234949Sbapt    nedges = 0;
297234949Sbapt
298234949Sbapt    rowp = F;
299234949Sbapt    for (i = 0; i < ngotos; i++)
300234949Sbapt    {
301234949Sbapt	stateno = to_state[i];
302234949Sbapt	sp = shift_table[stateno];
303234949Sbapt
304234949Sbapt	if (sp)
305234949Sbapt	{
306234949Sbapt	    k = sp->nshifts;
307234949Sbapt
308234949Sbapt	    for (j = 0; j < k; j++)
309234949Sbapt	    {
310234949Sbapt		symbol = accessing_symbol[sp->shift[j]];
311234949Sbapt		if (ISVAR(symbol))
312234949Sbapt		    break;
313234949Sbapt		SETBIT(rowp, symbol);
314234949Sbapt	    }
315234949Sbapt
316234949Sbapt	    for (; j < k; j++)
317234949Sbapt	    {
318234949Sbapt		symbol = accessing_symbol[sp->shift[j]];
319234949Sbapt		if (nullable[symbol])
320234949Sbapt		    edge[nedges++] = map_goto(stateno, symbol);
321234949Sbapt	    }
322234949Sbapt
323234949Sbapt	    if (nedges)
324234949Sbapt	    {
325234949Sbapt		reads[i] = rp = NEW2(nedges + 1, Value_t);
326234949Sbapt
327234949Sbapt		for (j = 0; j < nedges; j++)
328234949Sbapt		    rp[j] = edge[j];
329234949Sbapt
330234949Sbapt		rp[nedges] = -1;
331234949Sbapt		nedges = 0;
332234949Sbapt	    }
333234949Sbapt	}
334234949Sbapt
335234949Sbapt	rowp += tokensetsize;
336234949Sbapt    }
337234949Sbapt
338234949Sbapt    SETBIT(F, 0);
339234949Sbapt    digraph(reads);
340234949Sbapt
341234949Sbapt    for (i = 0; i < ngotos; i++)
342234949Sbapt    {
343234949Sbapt	if (reads[i])
344234949Sbapt	    FREE(reads[i]);
345234949Sbapt    }
346234949Sbapt
347234949Sbapt    FREE(reads);
348234949Sbapt    FREE(edge);
349234949Sbapt}
350234949Sbapt
351234949Sbaptstatic void
352234949Sbaptbuild_relations(void)
353234949Sbapt{
354234949Sbapt    int i;
355234949Sbapt    int j;
356234949Sbapt    int k;
357234949Sbapt    Value_t *rulep;
358234949Sbapt    Value_t *rp;
359234949Sbapt    shifts *sp;
360234949Sbapt    int length;
361234949Sbapt    int nedges;
362234949Sbapt    int done_flag;
363234949Sbapt    Value_t state1;
364234949Sbapt    Value_t stateno;
365234949Sbapt    int symbol1;
366234949Sbapt    int symbol2;
367234949Sbapt    Value_t *shortp;
368234949Sbapt    Value_t *edge;
369234949Sbapt    Value_t *states;
370234949Sbapt    Value_t **new_includes;
371234949Sbapt
372234949Sbapt    includes = NEW2(ngotos, Value_t *);
373234949Sbapt    edge = NEW2(ngotos + 1, Value_t);
374234949Sbapt    states = NEW2(maxrhs + 1, Value_t);
375234949Sbapt
376234949Sbapt    for (i = 0; i < ngotos; i++)
377234949Sbapt    {
378234949Sbapt	nedges = 0;
379234949Sbapt	state1 = from_state[i];
380234949Sbapt	symbol1 = accessing_symbol[to_state[i]];
381234949Sbapt
382234949Sbapt	for (rulep = derives[symbol1]; *rulep >= 0; rulep++)
383234949Sbapt	{
384234949Sbapt	    length = 1;
385234949Sbapt	    states[0] = state1;
386234949Sbapt	    stateno = state1;
387234949Sbapt
388234949Sbapt	    for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++)
389234949Sbapt	    {
390234949Sbapt		symbol2 = *rp;
391234949Sbapt		sp = shift_table[stateno];
392234949Sbapt		k = sp->nshifts;
393234949Sbapt
394234949Sbapt		for (j = 0; j < k; j++)
395234949Sbapt		{
396234949Sbapt		    stateno = sp->shift[j];
397234949Sbapt		    if (accessing_symbol[stateno] == symbol2)
398234949Sbapt			break;
399234949Sbapt		}
400234949Sbapt
401234949Sbapt		states[length++] = stateno;
402234949Sbapt	    }
403234949Sbapt
404234949Sbapt	    add_lookback_edge(stateno, *rulep, i);
405234949Sbapt
406234949Sbapt	    length--;
407234949Sbapt	    done_flag = 0;
408234949Sbapt	    while (!done_flag)
409234949Sbapt	    {
410234949Sbapt		done_flag = 1;
411234949Sbapt		rp--;
412234949Sbapt		if (ISVAR(*rp))
413234949Sbapt		{
414234949Sbapt		    stateno = states[--length];
415234949Sbapt		    edge[nedges++] = map_goto(stateno, *rp);
416234949Sbapt		    if (nullable[*rp] && length > 0)
417234949Sbapt			done_flag = 0;
418234949Sbapt		}
419234949Sbapt	    }
420234949Sbapt	}
421234949Sbapt
422234949Sbapt	if (nedges)
423234949Sbapt	{
424234949Sbapt	    includes[i] = shortp = NEW2(nedges + 1, Value_t);
425234949Sbapt	    for (j = 0; j < nedges; j++)
426234949Sbapt		shortp[j] = edge[j];
427234949Sbapt	    shortp[nedges] = -1;
428234949Sbapt	}
429234949Sbapt    }
430234949Sbapt
431234949Sbapt    new_includes = transpose(includes, ngotos);
432234949Sbapt
433234949Sbapt    for (i = 0; i < ngotos; i++)
434234949Sbapt	if (includes[i])
435234949Sbapt	    FREE(includes[i]);
436234949Sbapt
437234949Sbapt    FREE(includes);
438234949Sbapt
439234949Sbapt    includes = new_includes;
440234949Sbapt
441234949Sbapt    FREE(edge);
442234949Sbapt    FREE(states);
443234949Sbapt}
444234949Sbapt
445234949Sbaptstatic void
446234949Sbaptadd_lookback_edge(int stateno, int ruleno, int gotono)
447234949Sbapt{
448234949Sbapt    int i, k;
449234949Sbapt    int found;
450234949Sbapt    shorts *sp;
451234949Sbapt
452234949Sbapt    i = lookaheads[stateno];
453234949Sbapt    k = lookaheads[stateno + 1];
454234949Sbapt    found = 0;
455234949Sbapt    while (!found && i < k)
456234949Sbapt    {
457234949Sbapt	if (LAruleno[i] == ruleno)
458234949Sbapt	    found = 1;
459234949Sbapt	else
460234949Sbapt	    ++i;
461234949Sbapt    }
462234949Sbapt    assert(found);
463234949Sbapt
464234949Sbapt    sp = NEW(shorts);
465234949Sbapt    sp->next = lookback[i];
466319297Sdelphij    sp->value = (Value_t)gotono;
467234949Sbapt    lookback[i] = sp;
468234949Sbapt}
469234949Sbapt
470234949Sbaptstatic Value_t **
471319297Sdelphijtranspose(Value_t **R2, int n)
472234949Sbapt{
473234949Sbapt    Value_t **new_R;
474234949Sbapt    Value_t **temp_R;
475234949Sbapt    Value_t *nedges;
476234949Sbapt    Value_t *sp;
477234949Sbapt    int i;
478234949Sbapt    int k;
479234949Sbapt
480234949Sbapt    nedges = NEW2(n, Value_t);
481234949Sbapt
482234949Sbapt    for (i = 0; i < n; i++)
483234949Sbapt    {
484234949Sbapt	sp = R2[i];
485234949Sbapt	if (sp)
486234949Sbapt	{
487234949Sbapt	    while (*sp >= 0)
488234949Sbapt		nedges[*sp++]++;
489234949Sbapt	}
490234949Sbapt    }
491234949Sbapt
492234949Sbapt    new_R = NEW2(n, Value_t *);
493234949Sbapt    temp_R = NEW2(n, Value_t *);
494234949Sbapt
495234949Sbapt    for (i = 0; i < n; i++)
496234949Sbapt    {
497234949Sbapt	k = nedges[i];
498234949Sbapt	if (k > 0)
499234949Sbapt	{
500234949Sbapt	    sp = NEW2(k + 1, Value_t);
501234949Sbapt	    new_R[i] = sp;
502234949Sbapt	    temp_R[i] = sp;
503234949Sbapt	    sp[k] = -1;
504234949Sbapt	}
505234949Sbapt    }
506234949Sbapt
507234949Sbapt    FREE(nedges);
508234949Sbapt
509234949Sbapt    for (i = 0; i < n; i++)
510234949Sbapt    {
511234949Sbapt	sp = R2[i];
512234949Sbapt	if (sp)
513234949Sbapt	{
514234949Sbapt	    while (*sp >= 0)
515319297Sdelphij		*temp_R[*sp++]++ = (Value_t)i;
516234949Sbapt	}
517234949Sbapt    }
518234949Sbapt
519234949Sbapt    FREE(temp_R);
520234949Sbapt
521234949Sbapt    return (new_R);
522234949Sbapt}
523234949Sbapt
524234949Sbaptstatic void
525234949Sbaptcompute_FOLLOWS(void)
526234949Sbapt{
527234949Sbapt    digraph(includes);
528234949Sbapt}
529234949Sbapt
530234949Sbaptstatic void
531234949Sbaptcompute_lookaheads(void)
532234949Sbapt{
533234949Sbapt    int i, n;
534234949Sbapt    unsigned *fp1, *fp2, *fp3;
535234949Sbapt    shorts *sp, *next;
536234949Sbapt    unsigned *rowp;
537234949Sbapt
538234949Sbapt    rowp = LA;
539234949Sbapt    n = lookaheads[nstates];
540234949Sbapt    for (i = 0; i < n; i++)
541234949Sbapt    {
542234949Sbapt	fp3 = rowp + tokensetsize;
543234949Sbapt	for (sp = lookback[i]; sp; sp = sp->next)
544234949Sbapt	{
545234949Sbapt	    fp1 = rowp;
546234949Sbapt	    fp2 = F + tokensetsize * sp->value;
547234949Sbapt	    while (fp1 < fp3)
548234949Sbapt		*fp1++ |= *fp2++;
549234949Sbapt	}
550234949Sbapt	rowp = fp3;
551234949Sbapt    }
552234949Sbapt
553234949Sbapt    for (i = 0; i < n; i++)
554234949Sbapt	for (sp = lookback[i]; sp; sp = next)
555234949Sbapt	{
556234949Sbapt	    next = sp->next;
557234949Sbapt	    FREE(sp);
558234949Sbapt	}
559234949Sbapt
560234949Sbapt    FREE(lookback);
561234949Sbapt    FREE(F);
562234949Sbapt}
563234949Sbapt
564234949Sbaptstatic void
565319297Sdelphijdigraph(Value_t **relation)
566234949Sbapt{
567234949Sbapt    int i;
568234949Sbapt
569319297Sdelphij    infinity = (Value_t)(ngotos + 2);
570234949Sbapt    INDEX = NEW2(ngotos + 1, Value_t);
571234949Sbapt    VERTICES = NEW2(ngotos + 1, Value_t);
572234949Sbapt    top = 0;
573234949Sbapt
574234949Sbapt    R = relation;
575234949Sbapt
576234949Sbapt    for (i = 0; i < ngotos; i++)
577234949Sbapt	INDEX[i] = 0;
578234949Sbapt
579234949Sbapt    for (i = 0; i < ngotos; i++)
580234949Sbapt    {
581234949Sbapt	if (INDEX[i] == 0 && R[i])
582234949Sbapt	    traverse(i);
583234949Sbapt    }
584234949Sbapt
585234949Sbapt    FREE(INDEX);
586234949Sbapt    FREE(VERTICES);
587234949Sbapt}
588234949Sbapt
589234949Sbaptstatic void
590234949Sbapttraverse(int i)
591234949Sbapt{
592234949Sbapt    unsigned *fp1;
593234949Sbapt    unsigned *fp2;
594234949Sbapt    unsigned *fp3;
595234949Sbapt    int j;
596234949Sbapt    Value_t *rp;
597234949Sbapt
598234949Sbapt    Value_t height;
599234949Sbapt    unsigned *base;
600234949Sbapt
601319297Sdelphij    VERTICES[++top] = (Value_t)i;
602234949Sbapt    INDEX[i] = height = top;
603234949Sbapt
604234949Sbapt    base = F + i * tokensetsize;
605234949Sbapt    fp3 = base + tokensetsize;
606234949Sbapt
607234949Sbapt    rp = R[i];
608234949Sbapt    if (rp)
609234949Sbapt    {
610234949Sbapt	while ((j = *rp++) >= 0)
611234949Sbapt	{
612234949Sbapt	    if (INDEX[j] == 0)
613234949Sbapt		traverse(j);
614234949Sbapt
615234949Sbapt	    if (INDEX[i] > INDEX[j])
616234949Sbapt		INDEX[i] = INDEX[j];
617234949Sbapt
618234949Sbapt	    fp1 = base;
619234949Sbapt	    fp2 = F + j * tokensetsize;
620234949Sbapt
621234949Sbapt	    while (fp1 < fp3)
622234949Sbapt		*fp1++ |= *fp2++;
623234949Sbapt	}
624234949Sbapt    }
625234949Sbapt
626234949Sbapt    if (INDEX[i] == height)
627234949Sbapt    {
628234949Sbapt	for (;;)
629234949Sbapt	{
630234949Sbapt	    j = VERTICES[top--];
631234949Sbapt	    INDEX[j] = infinity;
632234949Sbapt
633234949Sbapt	    if (i == j)
634234949Sbapt		break;
635234949Sbapt
636234949Sbapt	    fp1 = base;
637234949Sbapt	    fp2 = F + j * tokensetsize;
638234949Sbapt
639234949Sbapt	    while (fp1 < fp3)
640234949Sbapt		*fp2++ = *fp1++;
641234949Sbapt	}
642234949Sbapt    }
643234949Sbapt}
644234949Sbapt
645234949Sbapt#ifdef NO_LEAKS
646234949Sbaptvoid
647234949Sbaptlalr_leaks(void)
648234949Sbapt{
649234949Sbapt    int i;
650234949Sbapt
651234949Sbapt    if (includes != 0)
652234949Sbapt    {
653234949Sbapt	for (i = 0; i < ngotos; i++)
654234949Sbapt	{
655234949Sbapt	    free(includes[i]);
656234949Sbapt	}
657234949Sbapt	DO_FREE(includes);
658234949Sbapt    }
659234949Sbapt}
660234949Sbapt#endif
661