]> git.saurik.com Git - bison.git/blame - src/lalr.c
* src/files.c (strsuffix): New.
[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"
d7913476 29#include "xalloc.h"
d0fb370f 30#include "gram.h"
a0f6b076 31#include "complain.h"
720d742f 32#include "lalr.h"
3519ec76 33#include "nullable.h"
340ef489 34#include "derives.h"
d0fb370f
RS
35
36int tokensetsize;
37short *lookaheads;
38short *LAruleno;
39unsigned *LA;
40short *accessing_symbol;
41char *consistent;
42core **state_table;
43shifts **shift_table;
44reductions **reduction_table;
45short *goto_map;
46short *from_state;
47short *to_state;
48
720d742f 49extern void berror PARAMS ((const char *));
d0fb370f
RS
50
51static int infinity;
52static int maxrhs;
53static int ngotos;
54static unsigned *F;
55static short **includes;
56static shorts **lookback;
57static short **R;
58static short *INDEX;
59static short *VERTICES;
60static int top;
61
62
720d742f
AD
63static void
64traverse (int i)
d0fb370f 65{
720d742f
AD
66 unsigned *fp1;
67 unsigned *fp2;
68 unsigned *fp3;
69 int j;
70 short *rp;
71
72 int height;
73 unsigned *base;
74
75 VERTICES[++top] = i;
76 INDEX[i] = height = top;
77
78 base = F + i * tokensetsize;
79 fp3 = base + tokensetsize;
80
81 rp = R[i];
82 if (rp)
83 {
84 while ((j = *rp++) >= 0)
85 {
86 if (INDEX[j] == 0)
87 traverse (j);
88
89 if (INDEX[i] > INDEX[j])
90 INDEX[i] = INDEX[j];
91
92 fp1 = base;
93 fp2 = F + j * tokensetsize;
94
95 while (fp1 < fp3)
96 *fp1++ |= *fp2++;
97 }
98 }
99
100 if (INDEX[i] == height)
101 {
102 for (;;)
103 {
104 j = VERTICES[top--];
105 INDEX[j] = infinity;
106
107 if (i == j)
108 break;
109
110 fp1 = base;
111 fp2 = F + j * tokensetsize;
112
113 while (fp1 < fp3)
114 *fp2++ = *fp1++;
115 }
116 }
d0fb370f
RS
117}
118
119
720d742f
AD
120static void
121digraph (short **relation)
122{
123 int i;
124
125 infinity = ngotos + 2;
d7913476
AD
126 INDEX = XCALLOC (short, ngotos + 1);
127 VERTICES = XCALLOC (short, ngotos + 1);
720d742f
AD
128 top = 0;
129
130 R = relation;
131
132 for (i = 0; i < ngotos; i++)
133 INDEX[i] = 0;
134
135 for (i = 0; i < ngotos; i++)
136 {
137 if (INDEX[i] == 0 && R[i])
138 traverse (i);
139 }
140
d7913476
AD
141 XFREE (INDEX);
142 XFREE (VERTICES);
720d742f
AD
143}
144
4a120d45 145static void
d2729d44 146set_state_table (void)
d0fb370f 147{
720d742f 148 core *sp;
d0fb370f 149
d7913476 150 state_table = XCALLOC (core *, nstates);
d0fb370f
RS
151
152 for (sp = first_state; sp; sp = sp->next)
153 state_table[sp->number] = sp;
154}
155
156
4a120d45 157static void
d2729d44 158set_accessing_symbol (void)
d0fb370f 159{
720d742f 160 core *sp;
d0fb370f 161
d7913476 162 accessing_symbol = XCALLOC (short, nstates);
d0fb370f
RS
163
164 for (sp = first_state; sp; sp = sp->next)
165 accessing_symbol[sp->number] = sp->accessing_symbol;
166}
167
168
4a120d45 169static void
d2729d44 170set_shift_table (void)
d0fb370f 171{
720d742f 172 shifts *sp;
d0fb370f 173
d7913476 174 shift_table = XCALLOC (shifts *, nstates);
d0fb370f
RS
175
176 for (sp = first_shift; sp; sp = sp->next)
177 shift_table[sp->number] = sp;
178}
179
180
4a120d45 181static void
d2729d44 182set_reduction_table (void)
d0fb370f 183{
720d742f 184 reductions *rp;
d0fb370f 185
d7913476 186 reduction_table = XCALLOC (reductions *, nstates);
d0fb370f
RS
187
188 for (rp = first_reduction; rp; rp = rp->next)
189 reduction_table[rp->number] = rp;
190}
191
192
4a120d45 193static void
d2729d44 194set_maxrhs (void)
d0fb370f 195{
720d742f
AD
196 short *itemp;
197 int length;
198 int max;
d0fb370f
RS
199
200 length = 0;
201 max = 0;
202 for (itemp = ritem; *itemp; itemp++)
203 {
204 if (*itemp > 0)
205 {
206 length++;
207 }
208 else
209 {
720d742f
AD
210 if (length > max)
211 max = length;
d0fb370f
RS
212 length = 0;
213 }
214 }
215
216 maxrhs = max;
217}
218
219
4a120d45 220static void
d2729d44 221initialize_LA (void)
d0fb370f 222{
720d742f
AD
223 int i;
224 int j;
225 int count;
226 reductions *rp;
227 shifts *sp;
228 short *np;
d0fb370f 229
d7913476
AD
230 consistent = XCALLOC (char, nstates);
231 lookaheads = XCALLOC (short, nstates + 1);
d0fb370f
RS
232
233 count = 0;
234 for (i = 0; i < nstates; i++)
235 {
720d742f 236 int k;
d0fb370f
RS
237
238 lookaheads[i] = count;
239
240 rp = reduction_table[i];
241 sp = shift_table[i];
242 if (rp && (rp->nreds > 1
720d742f 243 || (sp && !ISVAR (accessing_symbol[sp->shifts[0]]))))
d0fb370f
RS
244 count += rp->nreds;
245 else
246 consistent[i] = 1;
247
248 if (sp)
249 for (k = 0; k < sp->nshifts; k++)
250 {
251 if (accessing_symbol[sp->shifts[k]] == error_token_number)
252 {
253 consistent[i] = 0;
254 break;
255 }
256 }
257 }
258
259 lookaheads[nstates] = count;
260
261 if (count == 0)
262 {
d7913476
AD
263 LA = XCALLOC (unsigned, 1 * tokensetsize);
264 LAruleno = XCALLOC (short, 1);
265 lookback = XCALLOC (shorts *, 1);
d0fb370f
RS
266 }
267 else
268 {
d7913476
AD
269 LA = XCALLOC (unsigned, count * tokensetsize);
270 LAruleno = XCALLOC (short, count);
271 lookback = XCALLOC (shorts *, count);
d0fb370f
RS
272 }
273
274 np = LAruleno;
275 for (i = 0; i < nstates; i++)
276 {
277 if (!consistent[i])
278 {
d2729d44 279 if ((rp = reduction_table[i]))
d0fb370f
RS
280 for (j = 0; j < rp->nreds; j++)
281 *np++ = rp->rules[j];
282 }
283 }
284}
285
286
4a120d45 287static void
d2729d44 288set_goto_map (void)
d0fb370f 289{
720d742f
AD
290 shifts *sp;
291 int i;
292 int symbol;
293 int k;
294 short *temp_map;
295 int state2;
296 int state1;
d0fb370f 297
d7913476
AD
298 goto_map = XCALLOC (short, nvars + 1) - ntokens;
299 temp_map = XCALLOC (short, nvars + 1) - ntokens;
d0fb370f
RS
300
301 ngotos = 0;
302 for (sp = first_shift; sp; sp = sp->next)
303 {
304 for (i = sp->nshifts - 1; i >= 0; i--)
305 {
306 symbol = accessing_symbol[sp->shifts[i]];
307
720d742f
AD
308 if (ISTOKEN (symbol))
309 break;
d0fb370f
RS
310
311 if (ngotos == MAXSHORT)
a0f6b076 312 fatal (_("too many gotos (max %d)"), MAXSHORT);
d0fb370f
RS
313
314 ngotos++;
315 goto_map[symbol]++;
720d742f 316 }
d0fb370f
RS
317 }
318
319 k = 0;
320 for (i = ntokens; i < nsyms; i++)
321 {
322 temp_map[i] = k;
323 k += goto_map[i];
324 }
325
326 for (i = ntokens; i < nsyms; i++)
327 goto_map[i] = temp_map[i];
328
329 goto_map[nsyms] = ngotos;
330 temp_map[nsyms] = ngotos;
331
d7913476
AD
332 from_state = XCALLOC (short, ngotos);
333 to_state = XCALLOC (short, ngotos);
d0fb370f
RS
334
335 for (sp = first_shift; sp; sp = sp->next)
336 {
337 state1 = sp->number;
338 for (i = sp->nshifts - 1; i >= 0; i--)
339 {
340 state2 = sp->shifts[i];
341 symbol = accessing_symbol[state2];
342
720d742f
AD
343 if (ISTOKEN (symbol))
344 break;
d0fb370f
RS
345
346 k = temp_map[symbol]++;
347 from_state[k] = state1;
348 to_state[k] = state2;
349 }
350 }
351
d7913476 352 XFREE (temp_map + ntokens);
d0fb370f
RS
353}
354
355
356
43591cec
AD
357/*----------------------------------------------------------.
358| Map a state/symbol pair into its numeric representation. |
359`----------------------------------------------------------*/
d0fb370f 360
4a120d45 361static int
d2729d44 362map_goto (int state, int symbol)
d0fb370f 363{
720d742f
AD
364 int high;
365 int low;
366 int middle;
367 int s;
d0fb370f
RS
368
369 low = goto_map[symbol];
370 high = goto_map[symbol + 1] - 1;
371
372 while (low <= high)
373 {
374 middle = (low + high) / 2;
375 s = from_state[middle];
376 if (s == state)
36281465 377 return middle;
d0fb370f
RS
378 else if (s < state)
379 low = middle + 1;
380 else
381 high = middle - 1;
382 }
383
43591cec
AD
384 assert (0);
385 /* NOTREACHED */
d0fb370f
RS
386 return 0;
387}
388
389
4a120d45 390static void
d2729d44 391initialize_F (void)
d0fb370f 392{
720d742f
AD
393 int i;
394 int j;
395 int k;
396 shifts *sp;
397 short *edge;
398 unsigned *rowp;
399 short *rp;
400 short **reads;
401 int nedges;
402 int stateno;
403 int symbol;
404 int nwords;
d0fb370f
RS
405
406 nwords = ngotos * tokensetsize;
d7913476 407 F = XCALLOC (unsigned, nwords);
d0fb370f 408
d7913476
AD
409 reads = XCALLOC (short *, ngotos);
410 edge = XCALLOC (short, ngotos + 1);
d0fb370f
RS
411 nedges = 0;
412
413 rowp = F;
414 for (i = 0; i < ngotos; i++)
415 {
416 stateno = to_state[i];
417 sp = shift_table[stateno];
418
419 if (sp)
420 {
421 k = sp->nshifts;
422
423 for (j = 0; j < k; j++)
424 {
425 symbol = accessing_symbol[sp->shifts[j]];
720d742f 426 if (ISVAR (symbol))
d0fb370f 427 break;
720d742f 428 SETBIT (rowp, symbol);
d0fb370f
RS
429 }
430
431 for (; j < k; j++)
432 {
433 symbol = accessing_symbol[sp->shifts[j]];
434 if (nullable[symbol])
720d742f 435 edge[nedges++] = map_goto (stateno, symbol);
d0fb370f 436 }
a0f6b076 437
d0fb370f
RS
438 if (nedges)
439 {
d7913476 440 reads[i] = rp = XCALLOC (short, nedges + 1);
d0fb370f
RS
441
442 for (j = 0; j < nedges; j++)
443 rp[j] = edge[j];
444
445 rp[nedges] = -1;
446 nedges = 0;
447 }
448 }
449
450 rowp += tokensetsize;
451 }
452
720d742f 453 digraph (reads);
d0fb370f
RS
454
455 for (i = 0; i < ngotos; i++)
456 {
457 if (reads[i])
d7913476 458 XFREE (reads[i]);
d0fb370f
RS
459 }
460
d7913476
AD
461 XFREE (reads);
462 XFREE (edge);
d0fb370f
RS
463}
464
465
4a120d45 466static void
d2729d44 467add_lookback_edge (int stateno, int ruleno, int gotono)
d0fb370f 468{
720d742f
AD
469 int i;
470 int k;
471 int found;
472 shorts *sp;
d0fb370f
RS
473
474 i = lookaheads[stateno];
475 k = lookaheads[stateno + 1];
476 found = 0;
477 while (!found && i < k)
478 {
479 if (LAruleno[i] == ruleno)
480 found = 1;
481 else
482 i++;
483 }
484
340ef489 485 assert (found);
d0fb370f 486
d7913476 487 sp = XCALLOC (shorts, 1);
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
d7913476 504 nedges = XCALLOC (short, n);
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
d7913476
AD
516 new_R = XCALLOC (short *, n);
517 temp_R = XCALLOC (short *, n);
d0fb370f
RS
518
519 for (i = 0; i < n; i++)
520 {
521 k = nedges[i];
522 if (k > 0)
523 {
d7913476 524 sp = XCALLOC (short, k + 1);
d0fb370f
RS
525 new_R[i] = sp;
526 temp_R[i] = sp;
527 sp[k] = -1;
528 }
529 }
530
d7913476 531 XFREE (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
d7913476 543 XFREE (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
d7913476
AD
570 includes = XCALLOC (short *, ngotos);
571 edge = XCALLOC (short, ngotos + 1);
572 states = XCALLOC (short, maxrhs + 1);
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 {
d7913476 624 includes[i] = shortp = XCALLOC (short, nedges + 1);
720d742f
AD
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])
d7913476 635 XFREE (includes[i]);
720d742f 636
d7913476 637 XFREE (includes);
720d742f
AD
638
639 includes = new_includes;
640
d7913476
AD
641 XFREE (edge);
642 XFREE (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 656 if (includes[i])
d7913476 657 XFREE (includes[i]);
d0fb370f
RS
658 }
659
d7913476 660 XFREE (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 697 sptmp = sp->next;
d7913476 698 XFREE (sp);
720d742f
AD
699 }
700 }
d0fb370f 701
d7913476
AD
702 XFREE (lookback);
703 XFREE (F);
720d742f 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}