lalr.c revision 268899
1226458Sdas/* $Id: lalr.c,v 1.10 2014/02/19 00:35:17 Tom.Shields Exp $ */
2226458Sdas
3226458Sdas#include "defs.h"
4226458Sdas
5226458Sdastypedef struct shorts
6226458Sdas{
7226458Sdas    struct shorts *next;
8226458Sdas    Value_t value;
9226458Sdas}
10226458Sdasshorts;
11226458Sdas
12226458Sdasstatic Value_t map_goto(int state, int symbol);
13226458Sdasstatic Value_t **transpose(Value_t ** R, int n);
14226458Sdasstatic void add_lookback_edge(int stateno, int ruleno, int gotono);
15226458Sdasstatic void build_relations(void);
16226458Sdasstatic void compute_FOLLOWS(void);
17226458Sdasstatic void compute_lookaheads(void);
18226458Sdasstatic void digraph(Value_t ** relation);
19226458Sdasstatic void initialize_F(void);
20226458Sdasstatic void initialize_LA(void);
21226458Sdasstatic void set_accessing_symbol(void);
22226458Sdasstatic void set_goto_map(void);
23226458Sdasstatic void set_maxrhs(void);
24226458Sdasstatic void set_reduction_table(void);
25226458Sdasstatic void set_shift_table(void);
26226458Sdasstatic void set_state_table(void);
27226458Sdasstatic void traverse(int i);
28226458Sdas
29226458Sdasstatic int tokensetsize;
30226458SdasValue_t *lookaheads;
31226458SdasValue_t *LAruleno;
32226458Sdasunsigned *LA;
33226458SdasValue_t *accessing_symbol;
34226458Sdascore **state_table;
35226458Sdasshifts **shift_table;
36226458Sdasreductions **reduction_table;
37226458SdasValue_t *goto_map;
38226458SdasValue_t *from_state;
39226458SdasValue_t *to_state;
40226458Sdas
41226458Sdasstatic Value_t infinity;
42226458Sdasstatic int maxrhs;
43226458Sdasstatic int ngotos;
44226458Sdasstatic unsigned *F;
45226599Sdasstatic Value_t **includes;
46226599Sdasstatic shorts **lookback;
47226458Sdasstatic Value_t **R;
48226458Sdasstatic Value_t *INDEX;
49226458Sdasstatic Value_t *VERTICES;
50226599Sdasstatic Value_t top;
51226458Sdas
52226458Sdasvoid
53226458Sdaslalr(void)
54226458Sdas{
55226458Sdas    tokensetsize = WORDSIZE(ntokens);
56226458Sdas
57226458Sdas    set_state_table();
58226458Sdas    set_accessing_symbol();
59226458Sdas    set_shift_table();
60226458Sdas    set_reduction_table();
61226458Sdas    set_maxrhs();
62226458Sdas    initialize_LA();
63226458Sdas    set_goto_map();
64226458Sdas    initialize_F();
65226458Sdas    build_relations();
66226599Sdas    compute_FOLLOWS();
67226599Sdas    compute_lookaheads();
68226599Sdas}
69226599Sdas
70226599Sdasstatic void
71226599Sdasset_state_table(void)
72226599Sdas{
73226599Sdas    core *sp;
74226599Sdas
75226599Sdas    state_table = NEW2(nstates, core *);
76226599Sdas    for (sp = first_state; sp; sp = sp->next)
77226599Sdas	state_table[sp->number] = sp;
78226599Sdas}
79226599Sdas
80226599Sdasstatic void
81226599Sdasset_accessing_symbol(void)
82226599Sdas{
83226458Sdas    core *sp;
84226458Sdas
85226458Sdas    accessing_symbol = NEW2(nstates, Value_t);
86226458Sdas    for (sp = first_state; sp; sp = sp->next)
87226458Sdas	accessing_symbol[sp->number] = sp->accessing_symbol;
88226458Sdas}
89226458Sdas
90226458Sdasstatic void
91226458Sdasset_shift_table(void)
92226458Sdas{
93226458Sdas    shifts *sp;
94226458Sdas
95226458Sdas    shift_table = NEW2(nstates, shifts *);
96226458Sdas    for (sp = first_shift; sp; sp = sp->next)
97226458Sdas	shift_table[sp->number] = sp;
98226599Sdas}
99226458Sdas
100226458Sdasstatic void
101226458Sdasset_reduction_table(void)
102226458Sdas{
103226458Sdas    reductions *rp;
104226599Sdas
105226458Sdas    reduction_table = NEW2(nstates, reductions *);
106226458Sdas    for (rp = first_reduction; rp; rp = rp->next)
107226458Sdas	reduction_table[rp->number] = rp;
108226458Sdas}
109226458Sdas
110226458Sdasstatic void
111226458Sdasset_maxrhs(void)
112226458Sdas{
113226458Sdas    Value_t *itemp;
114226458Sdas    Value_t *item_end;
115226458Sdas    int length;
116226458Sdas    int max;
117226458Sdas
118226458Sdas    length = 0;
119226458Sdas    max = 0;
120226458Sdas    item_end = ritem + nitems;
121226458Sdas    for (itemp = ritem; itemp < item_end; itemp++)
122226458Sdas    {
123226458Sdas	if (*itemp >= 0)
124226458Sdas	{
125226458Sdas	    length++;
126226458Sdas	}
127226458Sdas	else
128226458Sdas	{
129226458Sdas	    if (length > max)
130226458Sdas		max = length;
131226458Sdas	    length = 0;
132226458Sdas	}
133226458Sdas    }
134226458Sdas
135226458Sdas    maxrhs = max;
136226458Sdas}
137226458Sdas
138226458Sdasstatic void
139226458Sdasinitialize_LA(void)
140226458Sdas{
141226458Sdas    int i, j, k;
142226458Sdas    reductions *rp;
143226458Sdas
144226458Sdas    lookaheads = NEW2(nstates + 1, Value_t);
145226458Sdas
146226458Sdas    k = 0;
147226458Sdas    for (i = 0; i < nstates; i++)
148226458Sdas    {
149226458Sdas	lookaheads[i] = (Value_t) k;
150226458Sdas	rp = reduction_table[i];
151226458Sdas	if (rp)
152226458Sdas	    k += rp->nreds;
153226458Sdas    }
154226458Sdas    lookaheads[nstates] = (Value_t) k;
155226458Sdas
156226458Sdas    LA = NEW2(k * tokensetsize, unsigned);
157226458Sdas    LAruleno = NEW2(k, Value_t);
158    lookback = NEW2(k, shorts *);
159
160    k = 0;
161    for (i = 0; i < nstates; i++)
162    {
163	rp = reduction_table[i];
164	if (rp)
165	{
166	    for (j = 0; j < rp->nreds; j++)
167	    {
168		LAruleno[k] = rp->rules[j];
169		k++;
170	    }
171	}
172    }
173}
174
175static void
176set_goto_map(void)
177{
178    shifts *sp;
179    int i;
180    int symbol;
181    int k;
182    Value_t *temp_map;
183    Value_t state2;
184    Value_t state1;
185
186    goto_map = NEW2(nvars + 1, Value_t) - ntokens;
187    temp_map = NEW2(nvars + 1, Value_t) - ntokens;
188
189    ngotos = 0;
190    for (sp = first_shift; sp; sp = sp->next)
191    {
192	for (i = sp->nshifts - 1; i >= 0; i--)
193	{
194	    symbol = accessing_symbol[sp->shift[i]];
195
196	    if (ISTOKEN(symbol))
197		break;
198
199	    if (ngotos == MAXYYINT)
200		fatal("too many gotos");
201
202	    ngotos++;
203	    goto_map[symbol]++;
204	}
205    }
206
207    k = 0;
208    for (i = ntokens; i < nsyms; i++)
209    {
210	temp_map[i] = (Value_t) k;
211	k += goto_map[i];
212    }
213
214    for (i = ntokens; i < nsyms; i++)
215	goto_map[i] = temp_map[i];
216
217    goto_map[nsyms] = (Value_t) ngotos;
218    temp_map[nsyms] = (Value_t) ngotos;
219
220    from_state = NEW2(ngotos, Value_t);
221    to_state = NEW2(ngotos, Value_t);
222
223    for (sp = first_shift; sp; sp = sp->next)
224    {
225	state1 = sp->number;
226	for (i = sp->nshifts - 1; i >= 0; i--)
227	{
228	    state2 = sp->shift[i];
229	    symbol = accessing_symbol[state2];
230
231	    if (ISTOKEN(symbol))
232		break;
233
234	    k = temp_map[symbol]++;
235	    from_state[k] = state1;
236	    to_state[k] = state2;
237	}
238    }
239
240    FREE(temp_map + ntokens);
241}
242
243/*  Map_goto maps a state/symbol pair into its numeric representation.	*/
244
245static Value_t
246map_goto(int state, int symbol)
247{
248    int high;
249    int low;
250    int middle;
251    int s;
252
253    low = goto_map[symbol];
254    high = goto_map[symbol + 1];
255
256    for (;;)
257    {
258	assert(low <= high);
259	middle = (low + high) >> 1;
260	s = from_state[middle];
261	if (s == state)
262	    return (Value_t) (middle);
263	else if (s < state)
264	    low = middle + 1;
265	else
266	    high = middle - 1;
267    }
268}
269
270static void
271initialize_F(void)
272{
273    int i;
274    int j;
275    int k;
276    shifts *sp;
277    Value_t *edge;
278    unsigned *rowp;
279    Value_t *rp;
280    Value_t **reads;
281    int nedges;
282    int stateno;
283    int symbol;
284    int nwords;
285
286    nwords = ngotos * tokensetsize;
287    F = NEW2(nwords, unsigned);
288
289    reads = NEW2(ngotos, Value_t *);
290    edge = NEW2(ngotos + 1, Value_t);
291    nedges = 0;
292
293    rowp = F;
294    for (i = 0; i < ngotos; i++)
295    {
296	stateno = to_state[i];
297	sp = shift_table[stateno];
298
299	if (sp)
300	{
301	    k = sp->nshifts;
302
303	    for (j = 0; j < k; j++)
304	    {
305		symbol = accessing_symbol[sp->shift[j]];
306		if (ISVAR(symbol))
307		    break;
308		SETBIT(rowp, symbol);
309	    }
310
311	    for (; j < k; j++)
312	    {
313		symbol = accessing_symbol[sp->shift[j]];
314		if (nullable[symbol])
315		    edge[nedges++] = map_goto(stateno, symbol);
316	    }
317
318	    if (nedges)
319	    {
320		reads[i] = rp = NEW2(nedges + 1, Value_t);
321
322		for (j = 0; j < nedges; j++)
323		    rp[j] = edge[j];
324
325		rp[nedges] = -1;
326		nedges = 0;
327	    }
328	}
329
330	rowp += tokensetsize;
331    }
332
333    SETBIT(F, 0);
334    digraph(reads);
335
336    for (i = 0; i < ngotos; i++)
337    {
338	if (reads[i])
339	    FREE(reads[i]);
340    }
341
342    FREE(reads);
343    FREE(edge);
344}
345
346static void
347build_relations(void)
348{
349    int i;
350    int j;
351    int k;
352    Value_t *rulep;
353    Value_t *rp;
354    shifts *sp;
355    int length;
356    int nedges;
357    int done_flag;
358    Value_t state1;
359    Value_t stateno;
360    int symbol1;
361    int symbol2;
362    Value_t *shortp;
363    Value_t *edge;
364    Value_t *states;
365    Value_t **new_includes;
366
367    includes = NEW2(ngotos, Value_t *);
368    edge = NEW2(ngotos + 1, Value_t);
369    states = NEW2(maxrhs + 1, Value_t);
370
371    for (i = 0; i < ngotos; i++)
372    {
373	nedges = 0;
374	state1 = from_state[i];
375	symbol1 = accessing_symbol[to_state[i]];
376
377	for (rulep = derives[symbol1]; *rulep >= 0; rulep++)
378	{
379	    length = 1;
380	    states[0] = state1;
381	    stateno = state1;
382
383	    for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++)
384	    {
385		symbol2 = *rp;
386		sp = shift_table[stateno];
387		k = sp->nshifts;
388
389		for (j = 0; j < k; j++)
390		{
391		    stateno = sp->shift[j];
392		    if (accessing_symbol[stateno] == symbol2)
393			break;
394		}
395
396		states[length++] = stateno;
397	    }
398
399	    add_lookback_edge(stateno, *rulep, i);
400
401	    length--;
402	    done_flag = 0;
403	    while (!done_flag)
404	    {
405		done_flag = 1;
406		rp--;
407		if (ISVAR(*rp))
408		{
409		    stateno = states[--length];
410		    edge[nedges++] = map_goto(stateno, *rp);
411		    if (nullable[*rp] && length > 0)
412			done_flag = 0;
413		}
414	    }
415	}
416
417	if (nedges)
418	{
419	    includes[i] = shortp = NEW2(nedges + 1, Value_t);
420	    for (j = 0; j < nedges; j++)
421		shortp[j] = edge[j];
422	    shortp[nedges] = -1;
423	}
424    }
425
426    new_includes = transpose(includes, ngotos);
427
428    for (i = 0; i < ngotos; i++)
429	if (includes[i])
430	    FREE(includes[i]);
431
432    FREE(includes);
433
434    includes = new_includes;
435
436    FREE(edge);
437    FREE(states);
438}
439
440static void
441add_lookback_edge(int stateno, int ruleno, int gotono)
442{
443    int i, k;
444    int found;
445    shorts *sp;
446
447    i = lookaheads[stateno];
448    k = lookaheads[stateno + 1];
449    found = 0;
450    while (!found && i < k)
451    {
452	if (LAruleno[i] == ruleno)
453	    found = 1;
454	else
455	    ++i;
456    }
457    assert(found);
458
459    sp = NEW(shorts);
460    sp->next = lookback[i];
461    sp->value = (Value_t) gotono;
462    lookback[i] = sp;
463}
464
465static Value_t **
466transpose(Value_t ** R2, int n)
467{
468    Value_t **new_R;
469    Value_t **temp_R;
470    Value_t *nedges;
471    Value_t *sp;
472    int i;
473    int k;
474
475    nedges = NEW2(n, Value_t);
476
477    for (i = 0; i < n; i++)
478    {
479	sp = R2[i];
480	if (sp)
481	{
482	    while (*sp >= 0)
483		nedges[*sp++]++;
484	}
485    }
486
487    new_R = NEW2(n, Value_t *);
488    temp_R = NEW2(n, Value_t *);
489
490    for (i = 0; i < n; i++)
491    {
492	k = nedges[i];
493	if (k > 0)
494	{
495	    sp = NEW2(k + 1, Value_t);
496	    new_R[i] = sp;
497	    temp_R[i] = sp;
498	    sp[k] = -1;
499	}
500    }
501
502    FREE(nedges);
503
504    for (i = 0; i < n; i++)
505    {
506	sp = R2[i];
507	if (sp)
508	{
509	    while (*sp >= 0)
510		*temp_R[*sp++]++ = (Value_t) i;
511	}
512    }
513
514    FREE(temp_R);
515
516    return (new_R);
517}
518
519static void
520compute_FOLLOWS(void)
521{
522    digraph(includes);
523}
524
525static void
526compute_lookaheads(void)
527{
528    int i, n;
529    unsigned *fp1, *fp2, *fp3;
530    shorts *sp, *next;
531    unsigned *rowp;
532
533    rowp = LA;
534    n = lookaheads[nstates];
535    for (i = 0; i < n; i++)
536    {
537	fp3 = rowp + tokensetsize;
538	for (sp = lookback[i]; sp; sp = sp->next)
539	{
540	    fp1 = rowp;
541	    fp2 = F + tokensetsize * sp->value;
542	    while (fp1 < fp3)
543		*fp1++ |= *fp2++;
544	}
545	rowp = fp3;
546    }
547
548    for (i = 0; i < n; i++)
549	for (sp = lookback[i]; sp; sp = next)
550	{
551	    next = sp->next;
552	    FREE(sp);
553	}
554
555    FREE(lookback);
556    FREE(F);
557}
558
559static void
560digraph(Value_t ** relation)
561{
562    int i;
563
564    infinity = (Value_t) (ngotos + 2);
565    INDEX = NEW2(ngotos + 1, Value_t);
566    VERTICES = NEW2(ngotos + 1, Value_t);
567    top = 0;
568
569    R = relation;
570
571    for (i = 0; i < ngotos; i++)
572	INDEX[i] = 0;
573
574    for (i = 0; i < ngotos; i++)
575    {
576	if (INDEX[i] == 0 && R[i])
577	    traverse(i);
578    }
579
580    FREE(INDEX);
581    FREE(VERTICES);
582}
583
584static void
585traverse(int i)
586{
587    unsigned *fp1;
588    unsigned *fp2;
589    unsigned *fp3;
590    int j;
591    Value_t *rp;
592
593    Value_t height;
594    unsigned *base;
595
596    VERTICES[++top] = (Value_t) i;
597    INDEX[i] = height = top;
598
599    base = F + i * tokensetsize;
600    fp3 = base + tokensetsize;
601
602    rp = R[i];
603    if (rp)
604    {
605	while ((j = *rp++) >= 0)
606	{
607	    if (INDEX[j] == 0)
608		traverse(j);
609
610	    if (INDEX[i] > INDEX[j])
611		INDEX[i] = INDEX[j];
612
613	    fp1 = base;
614	    fp2 = F + j * tokensetsize;
615
616	    while (fp1 < fp3)
617		*fp1++ |= *fp2++;
618	}
619    }
620
621    if (INDEX[i] == height)
622    {
623	for (;;)
624	{
625	    j = VERTICES[top--];
626	    INDEX[j] = infinity;
627
628	    if (i == j)
629		break;
630
631	    fp1 = base;
632	    fp2 = F + j * tokensetsize;
633
634	    while (fp1 < fp3)
635		*fp2++ = *fp1++;
636	}
637    }
638}
639
640#ifdef NO_LEAKS
641void
642lalr_leaks(void)
643{
644    int i;
645
646    if (includes != 0)
647    {
648	for (i = 0; i < ngotos; i++)
649	{
650	    free(includes[i]);
651	}
652	DO_FREE(includes);
653    }
654}
655#endif
656