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