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