]> git.saurik.com Git - bison.git/blame - src/lalr.c
* src/nullable.h: New file.
[bison.git] / src / lalr.c
CommitLineData
d0fb370f
RS
1/* Compute look-ahead criteria for bison,
2 Copyright (C) 1984, 1986, 1989 Free Software Foundation, Inc.
3
4This file is part of Bison, the GNU Compiler Compiler.
5
6Bison is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11Bison is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with Bison; see the file COPYING. If not, write to
c49a8e71
JT
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
d0fb370f
RS
20
21
720d742f
AD
22/* Compute how to make the finite state machine deterministic; find
23 which rules need lookahead in each state, and which lookahead
24 tokens they accept. */
d0fb370f 25
d0fb370f 26#include "system.h"
d0fb370f
RS
27#include "types.h"
28#include "state.h"
7612000c 29#include "alloc.h"
d0fb370f 30#include "gram.h"
a0f6b076 31#include "complain.h"
720d742f 32#include "lalr.h"
3519ec76 33#include "nullable.h"
d0fb370f
RS
34
35extern short **derives;
d0fb370f
RS
36
37int tokensetsize;
38short *lookaheads;
39short *LAruleno;
40unsigned *LA;
41short *accessing_symbol;
42char *consistent;
43core **state_table;
44shifts **shift_table;
45reductions **reduction_table;
46short *goto_map;
47short *from_state;
48short *to_state;
49
720d742f 50extern void berror PARAMS ((const char *));
d0fb370f
RS
51
52static int infinity;
53static int maxrhs;
54static int ngotos;
55static unsigned *F;
56static short **includes;
57static shorts **lookback;
58static short **R;
59static short *INDEX;
60static short *VERTICES;
61static int top;
62
63
720d742f
AD
64static void
65traverse (int i)
d0fb370f 66{
720d742f
AD
67 unsigned *fp1;
68 unsigned *fp2;
69 unsigned *fp3;
70 int j;
71 short *rp;
72
73 int height;
74 unsigned *base;
75
76 VERTICES[++top] = i;
77 INDEX[i] = height = top;
78
79 base = F + i * tokensetsize;
80 fp3 = base + tokensetsize;
81
82 rp = R[i];
83 if (rp)
84 {
85 while ((j = *rp++) >= 0)
86 {
87 if (INDEX[j] == 0)
88 traverse (j);
89
90 if (INDEX[i] > INDEX[j])
91 INDEX[i] = INDEX[j];
92
93 fp1 = base;
94 fp2 = F + j * tokensetsize;
95
96 while (fp1 < fp3)
97 *fp1++ |= *fp2++;
98 }
99 }
100
101 if (INDEX[i] == height)
102 {
103 for (;;)
104 {
105 j = VERTICES[top--];
106 INDEX[j] = infinity;
107
108 if (i == j)
109 break;
110
111 fp1 = base;
112 fp2 = F + j * tokensetsize;
113
114 while (fp1 < fp3)
115 *fp2++ = *fp1++;
116 }
117 }
d0fb370f
RS
118}
119
120
720d742f
AD
121static void
122digraph (short **relation)
123{
124 int i;
125
126 infinity = ngotos + 2;
127 INDEX = NEW2 (ngotos + 1, short);
128 VERTICES = NEW2 (ngotos + 1, short);
129 top = 0;
130
131 R = relation;
132
133 for (i = 0; i < ngotos; i++)
134 INDEX[i] = 0;
135
136 for (i = 0; i < ngotos; i++)
137 {
138 if (INDEX[i] == 0 && R[i])
139 traverse (i);
140 }
141
142 FREE (INDEX);
143 FREE (VERTICES);
144}
145
4a120d45 146static void
d2729d44 147set_state_table (void)
d0fb370f 148{
720d742f 149 core *sp;
d0fb370f 150
720d742f 151 state_table = NEW2 (nstates, core *);
d0fb370f
RS
152
153 for (sp = first_state; sp; sp = sp->next)
154 state_table[sp->number] = sp;
155}
156
157
4a120d45 158static void
d2729d44 159set_accessing_symbol (void)
d0fb370f 160{
720d742f 161 core *sp;
d0fb370f 162
720d742f 163 accessing_symbol = NEW2 (nstates, short);
d0fb370f
RS
164
165 for (sp = first_state; sp; sp = sp->next)
166 accessing_symbol[sp->number] = sp->accessing_symbol;
167}
168
169
4a120d45 170static void
d2729d44 171set_shift_table (void)
d0fb370f 172{
720d742f 173 shifts *sp;
d0fb370f 174
720d742f 175 shift_table = NEW2 (nstates, shifts *);
d0fb370f
RS
176
177 for (sp = first_shift; sp; sp = sp->next)
178 shift_table[sp->number] = sp;
179}
180
181
4a120d45 182static void
d2729d44 183set_reduction_table (void)
d0fb370f 184{
720d742f 185 reductions *rp;
d0fb370f 186
720d742f 187 reduction_table = NEW2 (nstates, reductions *);
d0fb370f
RS
188
189 for (rp = first_reduction; rp; rp = rp->next)
190 reduction_table[rp->number] = rp;
191}
192
193
4a120d45 194static void
d2729d44 195set_maxrhs (void)
d0fb370f 196{
720d742f
AD
197 short *itemp;
198 int length;
199 int max;
d0fb370f
RS
200
201 length = 0;
202 max = 0;
203 for (itemp = ritem; *itemp; itemp++)
204 {
205 if (*itemp > 0)
206 {
207 length++;
208 }
209 else
210 {
720d742f
AD
211 if (length > max)
212 max = length;
d0fb370f
RS
213 length = 0;
214 }
215 }
216
217 maxrhs = max;
218}
219
220
4a120d45 221static void
d2729d44 222initialize_LA (void)
d0fb370f 223{
720d742f
AD
224 int i;
225 int j;
226 int count;
227 reductions *rp;
228 shifts *sp;
229 short *np;
d0fb370f 230
720d742f
AD
231 consistent = NEW2 (nstates, char);
232 lookaheads = NEW2 (nstates + 1, short);
d0fb370f
RS
233
234 count = 0;
235 for (i = 0; i < nstates; i++)
236 {
720d742f 237 int k;
d0fb370f
RS
238
239 lookaheads[i] = count;
240
241 rp = reduction_table[i];
242 sp = shift_table[i];
243 if (rp && (rp->nreds > 1
720d742f 244 || (sp && !ISVAR (accessing_symbol[sp->shifts[0]]))))
d0fb370f
RS
245 count += rp->nreds;
246 else
247 consistent[i] = 1;
248
249 if (sp)
250 for (k = 0; k < sp->nshifts; k++)
251 {
252 if (accessing_symbol[sp->shifts[k]] == error_token_number)
253 {
254 consistent[i] = 0;
255 break;
256 }
257 }
258 }
259
260 lookaheads[nstates] = count;
261
262 if (count == 0)
263 {
720d742f
AD
264 LA = NEW2 (1 * tokensetsize, unsigned);
265 LAruleno = NEW2 (1, short);
266 lookback = NEW2 (1, shorts *);
d0fb370f
RS
267 }
268 else
269 {
720d742f
AD
270 LA = NEW2 (count * tokensetsize, unsigned);
271 LAruleno = NEW2 (count, short);
272 lookback = NEW2 (count, shorts *);
d0fb370f
RS
273 }
274
275 np = LAruleno;
276 for (i = 0; i < nstates; i++)
277 {
278 if (!consistent[i])
279 {
d2729d44 280 if ((rp = reduction_table[i]))
d0fb370f
RS
281 for (j = 0; j < rp->nreds; j++)
282 *np++ = rp->rules[j];
283 }
284 }
285}
286
287
4a120d45 288static void
d2729d44 289set_goto_map (void)
d0fb370f 290{
720d742f
AD
291 shifts *sp;
292 int i;
293 int symbol;
294 int k;
295 short *temp_map;
296 int state2;
297 int state1;
d0fb370f 298
720d742f
AD
299 goto_map = NEW2 (nvars + 1, short) - ntokens;
300 temp_map = NEW2 (nvars + 1, short) - ntokens;
d0fb370f
RS
301
302 ngotos = 0;
303 for (sp = first_shift; sp; sp = sp->next)
304 {
305 for (i = sp->nshifts - 1; i >= 0; i--)
306 {
307 symbol = accessing_symbol[sp->shifts[i]];
308
720d742f
AD
309 if (ISTOKEN (symbol))
310 break;
d0fb370f
RS
311
312 if (ngotos == MAXSHORT)
a0f6b076 313 fatal (_("too many gotos (max %d)"), MAXSHORT);
d0fb370f
RS
314
315 ngotos++;
316 goto_map[symbol]++;
720d742f 317 }
d0fb370f
RS
318 }
319
320 k = 0;
321 for (i = ntokens; i < nsyms; i++)
322 {
323 temp_map[i] = k;
324 k += goto_map[i];
325 }
326
327 for (i = ntokens; i < nsyms; i++)
328 goto_map[i] = temp_map[i];
329
330 goto_map[nsyms] = ngotos;
331 temp_map[nsyms] = ngotos;
332
720d742f
AD
333 from_state = NEW2 (ngotos, short);
334 to_state = NEW2 (ngotos, short);
d0fb370f
RS
335
336 for (sp = first_shift; sp; sp = sp->next)
337 {
338 state1 = sp->number;
339 for (i = sp->nshifts - 1; i >= 0; i--)
340 {
341 state2 = sp->shifts[i];
342 symbol = accessing_symbol[state2];
343
720d742f
AD
344 if (ISTOKEN (symbol))
345 break;
d0fb370f
RS
346
347 k = temp_map[symbol]++;
348 from_state[k] = state1;
349 to_state[k] = state2;
350 }
351 }
352
720d742f 353 FREE (temp_map + ntokens);
d0fb370f
RS
354}
355
356
357
358/* Map_goto maps a state/symbol pair into its numeric representation. */
359
4a120d45 360static int
d2729d44 361map_goto (int state, int symbol)
d0fb370f 362{
720d742f
AD
363 int high;
364 int low;
365 int middle;
366 int s;
d0fb370f
RS
367
368 low = goto_map[symbol];
369 high = goto_map[symbol + 1] - 1;
370
371 while (low <= high)
372 {
373 middle = (low + high) / 2;
374 s = from_state[middle];
375 if (s == state)
36281465 376 return middle;
d0fb370f
RS
377 else if (s < state)
378 low = middle + 1;
379 else
380 high = middle - 1;
381 }
382
720d742f 383 berror ("map_goto");
d0fb370f
RS
384/* NOTREACHED */
385 return 0;
386}
387
388
4a120d45 389static void
d2729d44 390initialize_F (void)
d0fb370f 391{
720d742f
AD
392 int i;
393 int j;
394 int k;
395 shifts *sp;
396 short *edge;
397 unsigned *rowp;
398 short *rp;
399 short **reads;
400 int nedges;
401 int stateno;
402 int symbol;
403 int nwords;
d0fb370f
RS
404
405 nwords = ngotos * tokensetsize;
720d742f 406 F = NEW2 (nwords, unsigned);
d0fb370f 407
720d742f
AD
408 reads = NEW2 (ngotos, short *);
409 edge = NEW2 (ngotos + 1, short);
d0fb370f
RS
410 nedges = 0;
411
412 rowp = F;
413 for (i = 0; i < ngotos; i++)
414 {
415 stateno = to_state[i];
416 sp = shift_table[stateno];
417
418 if (sp)
419 {
420 k = sp->nshifts;
421
422 for (j = 0; j < k; j++)
423 {
424 symbol = accessing_symbol[sp->shifts[j]];
720d742f 425 if (ISVAR (symbol))
d0fb370f 426 break;
720d742f 427 SETBIT (rowp, symbol);
d0fb370f
RS
428 }
429
430 for (; j < k; j++)
431 {
432 symbol = accessing_symbol[sp->shifts[j]];
433 if (nullable[symbol])
720d742f 434 edge[nedges++] = map_goto (stateno, symbol);
d0fb370f 435 }
a0f6b076 436
d0fb370f
RS
437 if (nedges)
438 {
720d742f 439 reads[i] = rp = NEW2 (nedges + 1, short);
d0fb370f
RS
440
441 for (j = 0; j < nedges; j++)
442 rp[j] = edge[j];
443
444 rp[nedges] = -1;
445 nedges = 0;
446 }
447 }
448
449 rowp += tokensetsize;
450 }
451
720d742f 452 digraph (reads);
d0fb370f
RS
453
454 for (i = 0; i < ngotos; i++)
455 {
456 if (reads[i])
720d742f 457 FREE (reads[i]);
d0fb370f
RS
458 }
459
720d742f
AD
460 FREE (reads);
461 FREE (edge);
d0fb370f
RS
462}
463
464
4a120d45 465static void
d2729d44 466add_lookback_edge (int stateno, int ruleno, int gotono)
d0fb370f 467{
720d742f
AD
468 int i;
469 int k;
470 int found;
471 shorts *sp;
d0fb370f
RS
472
473 i = lookaheads[stateno];
474 k = lookaheads[stateno + 1];
475 found = 0;
476 while (!found && i < k)
477 {
478 if (LAruleno[i] == ruleno)
479 found = 1;
480 else
481 i++;
482 }
483
484 if (found == 0)
720d742f 485 berror ("add_lookback_edge");
d0fb370f 486
720d742f 487 sp = NEW (shorts);
d0fb370f
RS
488 sp->next = lookback[i];
489 sp->value = gotono;
490 lookback[i] = sp;
491}
492
493
4a120d45 494static short **
d2729d44 495transpose (short **R_arg, int n)
d0fb370f 496{
720d742f
AD
497 short **new_R;
498 short **temp_R;
499 short *nedges;
500 short *sp;
501 int i;
502 int k;
d0fb370f 503
720d742f 504 nedges = NEW2 (n, short);
d0fb370f
RS
505
506 for (i = 0; i < n; i++)
507 {
508 sp = R_arg[i];
509 if (sp)
510 {
511 while (*sp >= 0)
512 nedges[*sp++]++;
513 }
514 }
515
720d742f
AD
516 new_R = NEW2 (n, short *);
517 temp_R = NEW2 (n, short *);
d0fb370f
RS
518
519 for (i = 0; i < n; i++)
520 {
521 k = nedges[i];
522 if (k > 0)
523 {
720d742f 524 sp = NEW2 (k + 1, short);
d0fb370f
RS
525 new_R[i] = sp;
526 temp_R[i] = sp;
527 sp[k] = -1;
528 }
529 }
530
720d742f 531 FREE (nedges);
d0fb370f
RS
532
533 for (i = 0; i < n; i++)
534 {
535 sp = R_arg[i];
536 if (sp)
537 {
538 while (*sp >= 0)
539 *temp_R[*sp++]++ = i;
540 }
541 }
542
720d742f 543 FREE (temp_R);
d0fb370f 544
36281465 545 return new_R;
d0fb370f
RS
546}
547
548
4a120d45 549static void
720d742f 550build_relations (void)
d0fb370f 551{
720d742f
AD
552 int i;
553 int j;
554 int k;
555 short *rulep;
556 short *rp;
557 shifts *sp;
558 int length;
559 int nedges;
560 int done;
561 int state1;
562 int stateno;
563 int symbol1;
564 int symbol2;
565 short *shortp;
566 short *edge;
567 short *states;
568 short **new_includes;
569
570 includes = NEW2 (ngotos, short *);
571 edge = NEW2 (ngotos + 1, short);
572 states = NEW2 (maxrhs + 1, short);
d0fb370f
RS
573
574 for (i = 0; i < ngotos; i++)
575 {
720d742f
AD
576 nedges = 0;
577 state1 = from_state[i];
578 symbol1 = accessing_symbol[to_state[i]];
d0fb370f 579
720d742f
AD
580 for (rulep = derives[symbol1]; *rulep > 0; rulep++)
581 {
582 length = 1;
583 states[0] = state1;
584 stateno = state1;
d0fb370f 585
720d742f
AD
586 for (rp = ritem + rrhs[*rulep]; *rp > 0; rp++)
587 {
588 symbol2 = *rp;
589 sp = shift_table[stateno];
590 k = sp->nshifts;
d0fb370f 591
720d742f
AD
592 for (j = 0; j < k; j++)
593 {
594 stateno = sp->shifts[j];
595 if (accessing_symbol[stateno] == symbol2)
596 break;
597 }
d0fb370f 598
720d742f
AD
599 states[length++] = stateno;
600 }
601
602 if (!consistent[stateno])
603 add_lookback_edge (stateno, *rulep, i);
604
605 length--;
606 done = 0;
607 while (!done)
608 {
609 done = 1;
610 rp--;
611 /* JF added rp>=ritem && I hope to god its right! */
612 if (rp >= ritem && ISVAR (*rp))
613 {
614 stateno = states[--length];
615 edge[nedges++] = map_goto (stateno, *rp);
616 if (nullable[*rp])
617 done = 0;
618 }
619 }
d0fb370f
RS
620 }
621
720d742f
AD
622 if (nedges)
623 {
624 includes[i] = shortp = NEW2 (nedges + 1, short);
625 for (j = 0; j < nedges; j++)
626 shortp[j] = edge[j];
627 shortp[nedges] = -1;
628 }
d0fb370f
RS
629 }
630
720d742f 631 new_includes = transpose (includes, ngotos);
d0fb370f 632
720d742f
AD
633 for (i = 0; i < ngotos; i++)
634 if (includes[i])
635 FREE (includes[i]);
636
637 FREE (includes);
638
639 includes = new_includes;
640
641 FREE (edge);
642 FREE (states);
d0fb370f
RS
643}
644
645
720d742f 646
4a120d45 647static void
720d742f 648compute_FOLLOWS (void)
d0fb370f 649{
720d742f 650 int i;
d0fb370f 651
720d742f 652 digraph (includes);
d0fb370f
RS
653
654 for (i = 0; i < ngotos; i++)
655 {
720d742f
AD
656 if (includes[i])
657 FREE (includes[i]);
d0fb370f
RS
658 }
659
720d742f 660 FREE (includes);
d0fb370f
RS
661}
662
663
4a120d45 664static void
720d742f 665compute_lookaheads (void)
d0fb370f 666{
720d742f
AD
667 int i;
668 int n;
669 unsigned *fp1;
670 unsigned *fp2;
671 unsigned *fp3;
672 shorts *sp;
673 unsigned *rowp;
674 shorts *sptmp; /* JF */
d0fb370f 675
720d742f
AD
676 rowp = LA;
677 n = lookaheads[nstates];
678 for (i = 0; i < n; i++)
d0fb370f 679 {
720d742f
AD
680 fp3 = rowp + tokensetsize;
681 for (sp = lookback[i]; sp; sp = sp->next)
d0fb370f 682 {
720d742f
AD
683 fp1 = rowp;
684 fp2 = F + tokensetsize * sp->value;
d0fb370f
RS
685 while (fp1 < fp3)
686 *fp1++ |= *fp2++;
687 }
720d742f
AD
688
689 rowp = fp3;
d0fb370f
RS
690 }
691
720d742f 692 for (i = 0; i < n; i++)
d0fb370f 693 {
720d742f
AD
694 /* JF removed ref to freed storage */
695 for (sp = lookback[i]; sp; sp = sptmp)
d0fb370f 696 {
720d742f
AD
697 sptmp = sp->next;
698 FREE (sp);
699 }
700 }
d0fb370f 701
720d742f
AD
702 FREE (lookback);
703 FREE (F);
704}
d0fb370f 705
d0fb370f 706
720d742f
AD
707void
708lalr (void)
709{
710 tokensetsize = WORDSIZE (ntokens);
711
712 set_state_table ();
713 set_accessing_symbol ();
714 set_shift_table ();
715 set_reduction_table ();
716 set_maxrhs ();
717 initialize_LA ();
718 set_goto_map ();
719 initialize_F ();
720 build_relations ();
721 compute_FOLLOWS ();
722 compute_lookaheads ();
d0fb370f 723}