]> git.saurik.com Git - bison.git/blob - src/lalr.c
* src/reader.c (copy_comment2): Expect the input stream to be on
[bison.git] / src / lalr.c
1 /* Compute look-ahead criteria for bison,
2 Copyright (C) 1984, 1986, 1989, 2000 Free Software Foundation, Inc.
3
4 This file is part of Bison, the GNU Compiler Compiler.
5
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.
10
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.
15
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. */
20
21
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. */
25
26 #include "system.h"
27 #include "types.h"
28 #include "LR0.h"
29 #include "xalloc.h"
30 #include "gram.h"
31 #include "complain.h"
32 #include "lalr.h"
33 #include "nullable.h"
34 #include "derives.h"
35
36 int tokensetsize;
37 short *lookaheads;
38 short *LAruleno;
39 unsigned *LA;
40 short *accessing_symbol;
41 char *consistent;
42 core **state_table;
43 shifts **shift_table;
44 reductions **reduction_table;
45 short *goto_map;
46 short *from_state;
47 short *to_state;
48
49 extern void berror PARAMS ((const char *));
50
51 static int infinity;
52 static int maxrhs;
53 static int ngotos;
54 static unsigned *F;
55 static short **includes;
56 static shorts **lookback;
57 static short **R;
58 static short *INDEX;
59 static short *VERTICES;
60 static int top;
61
62
63 static void
64 traverse (int i)
65 {
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 }
117 }
118
119
120 static void
121 digraph (short **relation)
122 {
123 int i;
124
125 infinity = ngotos + 2;
126 INDEX = XCALLOC (short, ngotos + 1);
127 VERTICES = XCALLOC (short, ngotos + 1);
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
141 XFREE (INDEX);
142 XFREE (VERTICES);
143 }
144
145 static void
146 set_state_table (void)
147 {
148 core *sp;
149
150 state_table = XCALLOC (core *, nstates);
151
152 for (sp = first_state; sp; sp = sp->next)
153 state_table[sp->number] = sp;
154 }
155
156
157 static void
158 set_accessing_symbol (void)
159 {
160 core *sp;
161
162 accessing_symbol = XCALLOC (short, nstates);
163
164 for (sp = first_state; sp; sp = sp->next)
165 accessing_symbol[sp->number] = sp->accessing_symbol;
166 }
167
168
169 static void
170 set_shift_table (void)
171 {
172 shifts *sp;
173
174 shift_table = XCALLOC (shifts *, nstates);
175
176 for (sp = first_shift; sp; sp = sp->next)
177 shift_table[sp->number] = sp;
178 }
179
180
181 static void
182 set_reduction_table (void)
183 {
184 reductions *rp;
185
186 reduction_table = XCALLOC (reductions *, nstates);
187
188 for (rp = first_reduction; rp; rp = rp->next)
189 reduction_table[rp->number] = rp;
190 }
191
192
193 static void
194 set_maxrhs (void)
195 {
196 short *itemp;
197 int length;
198 int max;
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 {
210 if (length > max)
211 max = length;
212 length = 0;
213 }
214 }
215
216 maxrhs = max;
217 }
218
219
220 static void
221 initialize_LA (void)
222 {
223 int i;
224 int j;
225 int count;
226 reductions *rp;
227 shifts *sp;
228 short *np;
229
230 consistent = XCALLOC (char, nstates);
231 lookaheads = XCALLOC (short, nstates + 1);
232
233 count = 0;
234 for (i = 0; i < nstates; i++)
235 {
236 int k;
237
238 lookaheads[i] = count;
239
240 rp = reduction_table[i];
241 sp = shift_table[i];
242 if (rp && (rp->nreds > 1
243 || (sp && !ISVAR (accessing_symbol[sp->shifts[0]]))))
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 {
263 LA = XCALLOC (unsigned, 1 * tokensetsize);
264 LAruleno = XCALLOC (short, 1);
265 lookback = XCALLOC (shorts *, 1);
266 }
267 else
268 {
269 LA = XCALLOC (unsigned, count * tokensetsize);
270 LAruleno = XCALLOC (short, count);
271 lookback = XCALLOC (shorts *, count);
272 }
273
274 np = LAruleno;
275 for (i = 0; i < nstates; i++)
276 {
277 if (!consistent[i])
278 {
279 if ((rp = reduction_table[i]))
280 for (j = 0; j < rp->nreds; j++)
281 *np++ = rp->rules[j];
282 }
283 }
284 }
285
286
287 static void
288 set_goto_map (void)
289 {
290 shifts *sp;
291 int i;
292 int symbol;
293 int k;
294 short *temp_map;
295 int state2;
296 int state1;
297
298 goto_map = XCALLOC (short, nvars + 1) - ntokens;
299 temp_map = XCALLOC (short, nvars + 1) - ntokens;
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
308 if (ISTOKEN (symbol))
309 break;
310
311 if (ngotos == MAXSHORT)
312 fatal (_("too many gotos (max %d)"), MAXSHORT);
313
314 ngotos++;
315 goto_map[symbol]++;
316 }
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
332 from_state = XCALLOC (short, ngotos);
333 to_state = XCALLOC (short, ngotos);
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
343 if (ISTOKEN (symbol))
344 break;
345
346 k = temp_map[symbol]++;
347 from_state[k] = state1;
348 to_state[k] = state2;
349 }
350 }
351
352 XFREE (temp_map + ntokens);
353 }
354
355
356
357 /* Map_goto maps a state/symbol pair into its numeric representation. */
358
359 static int
360 map_goto (int state, int symbol)
361 {
362 int high;
363 int low;
364 int middle;
365 int s;
366
367 low = goto_map[symbol];
368 high = goto_map[symbol + 1] - 1;
369
370 while (low <= high)
371 {
372 middle = (low + high) / 2;
373 s = from_state[middle];
374 if (s == state)
375 return middle;
376 else if (s < state)
377 low = middle + 1;
378 else
379 high = middle - 1;
380 }
381
382 berror ("map_goto");
383 /* NOTREACHED */
384 return 0;
385 }
386
387
388 static void
389 initialize_F (void)
390 {
391 int i;
392 int j;
393 int k;
394 shifts *sp;
395 short *edge;
396 unsigned *rowp;
397 short *rp;
398 short **reads;
399 int nedges;
400 int stateno;
401 int symbol;
402 int nwords;
403
404 nwords = ngotos * tokensetsize;
405 F = XCALLOC (unsigned, nwords);
406
407 reads = XCALLOC (short *, ngotos);
408 edge = XCALLOC (short, ngotos + 1);
409 nedges = 0;
410
411 rowp = F;
412 for (i = 0; i < ngotos; i++)
413 {
414 stateno = to_state[i];
415 sp = shift_table[stateno];
416
417 if (sp)
418 {
419 k = sp->nshifts;
420
421 for (j = 0; j < k; j++)
422 {
423 symbol = accessing_symbol[sp->shifts[j]];
424 if (ISVAR (symbol))
425 break;
426 SETBIT (rowp, symbol);
427 }
428
429 for (; j < k; j++)
430 {
431 symbol = accessing_symbol[sp->shifts[j]];
432 if (nullable[symbol])
433 edge[nedges++] = map_goto (stateno, symbol);
434 }
435
436 if (nedges)
437 {
438 reads[i] = rp = XCALLOC (short, nedges + 1);
439
440 for (j = 0; j < nedges; j++)
441 rp[j] = edge[j];
442
443 rp[nedges] = -1;
444 nedges = 0;
445 }
446 }
447
448 rowp += tokensetsize;
449 }
450
451 digraph (reads);
452
453 for (i = 0; i < ngotos; i++)
454 {
455 if (reads[i])
456 XFREE (reads[i]);
457 }
458
459 XFREE (reads);
460 XFREE (edge);
461 }
462
463
464 static void
465 add_lookback_edge (int stateno, int ruleno, int gotono)
466 {
467 int i;
468 int k;
469 int found;
470 shorts *sp;
471
472 i = lookaheads[stateno];
473 k = lookaheads[stateno + 1];
474 found = 0;
475 while (!found && i < k)
476 {
477 if (LAruleno[i] == ruleno)
478 found = 1;
479 else
480 i++;
481 }
482
483 assert (found);
484
485 sp = XCALLOC (shorts, 1);
486 sp->next = lookback[i];
487 sp->value = gotono;
488 lookback[i] = sp;
489 }
490
491
492 static short **
493 transpose (short **R_arg, int n)
494 {
495 short **new_R;
496 short **temp_R;
497 short *nedges;
498 short *sp;
499 int i;
500 int k;
501
502 nedges = XCALLOC (short, n);
503
504 for (i = 0; i < n; i++)
505 {
506 sp = R_arg[i];
507 if (sp)
508 {
509 while (*sp >= 0)
510 nedges[*sp++]++;
511 }
512 }
513
514 new_R = XCALLOC (short *, n);
515 temp_R = XCALLOC (short *, n);
516
517 for (i = 0; i < n; i++)
518 {
519 k = nedges[i];
520 if (k > 0)
521 {
522 sp = XCALLOC (short, k + 1);
523 new_R[i] = sp;
524 temp_R[i] = sp;
525 sp[k] = -1;
526 }
527 }
528
529 XFREE (nedges);
530
531 for (i = 0; i < n; i++)
532 {
533 sp = R_arg[i];
534 if (sp)
535 {
536 while (*sp >= 0)
537 *temp_R[*sp++]++ = i;
538 }
539 }
540
541 XFREE (temp_R);
542
543 return new_R;
544 }
545
546
547 static void
548 build_relations (void)
549 {
550 int i;
551 int j;
552 int k;
553 short *rulep;
554 short *rp;
555 shifts *sp;
556 int length;
557 int nedges;
558 int done;
559 int state1;
560 int stateno;
561 int symbol1;
562 int symbol2;
563 short *shortp;
564 short *edge;
565 short *states;
566 short **new_includes;
567
568 includes = XCALLOC (short *, ngotos);
569 edge = XCALLOC (short, ngotos + 1);
570 states = XCALLOC (short, maxrhs + 1);
571
572 for (i = 0; i < ngotos; i++)
573 {
574 nedges = 0;
575 state1 = from_state[i];
576 symbol1 = accessing_symbol[to_state[i]];
577
578 for (rulep = derives[symbol1]; *rulep > 0; rulep++)
579 {
580 length = 1;
581 states[0] = state1;
582 stateno = state1;
583
584 for (rp = ritem + rrhs[*rulep]; *rp > 0; rp++)
585 {
586 symbol2 = *rp;
587 sp = shift_table[stateno];
588 k = sp->nshifts;
589
590 for (j = 0; j < k; j++)
591 {
592 stateno = sp->shifts[j];
593 if (accessing_symbol[stateno] == symbol2)
594 break;
595 }
596
597 states[length++] = stateno;
598 }
599
600 if (!consistent[stateno])
601 add_lookback_edge (stateno, *rulep, i);
602
603 length--;
604 done = 0;
605 while (!done)
606 {
607 done = 1;
608 rp--;
609 /* JF added rp>=ritem && I hope to god its right! */
610 if (rp >= ritem && ISVAR (*rp))
611 {
612 stateno = states[--length];
613 edge[nedges++] = map_goto (stateno, *rp);
614 if (nullable[*rp])
615 done = 0;
616 }
617 }
618 }
619
620 if (nedges)
621 {
622 includes[i] = shortp = XCALLOC (short, nedges + 1);
623 for (j = 0; j < nedges; j++)
624 shortp[j] = edge[j];
625 shortp[nedges] = -1;
626 }
627 }
628
629 new_includes = transpose (includes, ngotos);
630
631 for (i = 0; i < ngotos; i++)
632 if (includes[i])
633 XFREE (includes[i]);
634
635 XFREE (includes);
636
637 includes = new_includes;
638
639 XFREE (edge);
640 XFREE (states);
641 }
642
643
644
645 static void
646 compute_FOLLOWS (void)
647 {
648 int i;
649
650 digraph (includes);
651
652 for (i = 0; i < ngotos; i++)
653 {
654 if (includes[i])
655 XFREE (includes[i]);
656 }
657
658 XFREE (includes);
659 }
660
661
662 static void
663 compute_lookaheads (void)
664 {
665 int i;
666 int n;
667 unsigned *fp1;
668 unsigned *fp2;
669 unsigned *fp3;
670 shorts *sp;
671 unsigned *rowp;
672 shorts *sptmp; /* JF */
673
674 rowp = LA;
675 n = lookaheads[nstates];
676 for (i = 0; i < n; i++)
677 {
678 fp3 = rowp + tokensetsize;
679 for (sp = lookback[i]; sp; sp = sp->next)
680 {
681 fp1 = rowp;
682 fp2 = F + tokensetsize * sp->value;
683 while (fp1 < fp3)
684 *fp1++ |= *fp2++;
685 }
686
687 rowp = fp3;
688 }
689
690 for (i = 0; i < n; i++)
691 {
692 /* JF removed ref to freed storage */
693 for (sp = lookback[i]; sp; sp = sptmp)
694 {
695 sptmp = sp->next;
696 XFREE (sp);
697 }
698 }
699
700 XFREE (lookback);
701 XFREE (F);
702 }
703
704
705 void
706 lalr (void)
707 {
708 tokensetsize = WORDSIZE (ntokens);
709
710 set_state_table ();
711 set_accessing_symbol ();
712 set_shift_table ();
713 set_reduction_table ();
714 set_maxrhs ();
715 initialize_LA ();
716 set_goto_map ();
717 initialize_F ();
718 build_relations ();
719 compute_FOLLOWS ();
720 compute_lookaheads ();
721 }