]> git.saurik.com Git - bison.git/blob - src/conflicts.c
Various anti-`extern in *.c' changes.
[bison.git] / src / conflicts.c
1 /* Find and resolve or report look-ahead conflicts for bison,
2 Copyright (C) 1984, 1989, 1992, 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 it
7 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, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 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 the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
20
21 #include "system.h"
22 #include "getargs.h"
23 #include "alloc.h"
24 #include "files.h"
25 #include "gram.h"
26 #include "state.h"
27 #include "lalr.h"
28 #include "conflicts.h"
29 #include "reader.h"
30 #include "LR0.h"
31
32 int any_conflicts = 0;
33 errs **err_table;
34 int expected_conflicts;
35 static char *conflicts;
36
37 static unsigned *shiftset;
38 static unsigned *lookaheadset;
39 static int src_total;
40 static int rrc_total;
41 static int src_count;
42 static int rrc_count;
43 \f
44
45 static inline void
46 log_resolution (int state, int LAno, int token, char *resolution)
47 {
48 if (verboseflag)
49 fprintf (foutput,
50 _("\
51 Conflict in state %d between rule %d and token %s resolved as %s.\n"),
52 state, LAruleno[LAno], tags[token], resolution);
53 }
54
55
56 /*------------------------------------------------------------------.
57 | Turn off the shift recorded for the specified token in the |
58 | specified state. Used when we resolve a shift-reduce conflict in |
59 | favor of the reduction. |
60 `------------------------------------------------------------------*/
61
62 static void
63 flush_shift (int state, int token)
64 {
65 shifts *shiftp;
66 int k, i;
67
68 shiftp = shift_table[state];
69
70 if (shiftp)
71 {
72 k = shiftp->nshifts;
73 for (i = 0; i < k; i++)
74 {
75 if (shiftp->shifts[i]
76 && token == accessing_symbol[shiftp->shifts[i]])
77 (shiftp->shifts[i]) = 0;
78 }
79 }
80 }
81
82
83 /*------------------------------------------------------------------.
84 | Attempt to resolve shift-reduce conflict for one rule by means of |
85 | precedence declarations. It has already been checked that the |
86 | rule has a precedence. A conflict is resolved by modifying the |
87 | shift or reduce tables so that there is no longer a conflict. |
88 `------------------------------------------------------------------*/
89
90 static void
91 resolve_sr_conflict (int state, int lookaheadnum)
92 {
93 int i;
94 int mask;
95 unsigned *fp1;
96 unsigned *fp2;
97 int redprec;
98 errs *errp = (errs *) xmalloc (sizeof (errs) + ntokens * sizeof (short));
99 short *errtokens = errp->errs;
100
101 /* find the rule to reduce by to get precedence of reduction */
102 redprec = rprec[LAruleno[lookaheadnum]];
103
104 mask = 1;
105 fp1 = LA + lookaheadnum * tokensetsize;
106 fp2 = lookaheadset;
107 for (i = 0; i < ntokens; i++)
108 {
109 if ((mask & *fp2 & *fp1) && sprec[i])
110 /* Shift-reduce conflict occurs for token number i
111 and it has a precedence.
112 The precedence of shifting is that of token i. */
113 {
114 if (sprec[i] < redprec)
115 {
116 log_resolution (state, lookaheadnum, i, _("reduce"));
117 *fp2 &= ~mask; /* flush the shift for this token */
118 flush_shift (state, i);
119 }
120 else if (sprec[i] > redprec)
121 {
122 log_resolution (state, lookaheadnum, i, _("shift"));
123 *fp1 &= ~mask; /* flush the reduce for this token */
124 }
125 else
126 {
127 /* Matching precedence levels.
128 For left association, keep only the reduction.
129 For right association, keep only the shift.
130 For nonassociation, keep neither. */
131
132 switch (sassoc[i])
133 {
134 case RIGHT_ASSOC:
135 log_resolution (state, lookaheadnum, i, _("shift"));
136 break;
137
138 case LEFT_ASSOC:
139 log_resolution (state, lookaheadnum, i, _("reduce"));
140 break;
141
142 case NON_ASSOC:
143 log_resolution (state, lookaheadnum, i, _("an error"));
144 break;
145 }
146
147 if (sassoc[i] != RIGHT_ASSOC)
148 {
149 *fp2 &= ~mask; /* flush the shift for this token */
150 flush_shift (state, i);
151 }
152 if (sassoc[i] != LEFT_ASSOC)
153 {
154 *fp1 &= ~mask; /* flush the reduce for this token */
155 }
156 if (sassoc[i] == NON_ASSOC)
157 {
158 /* Record an explicit error for this token. */
159 *errtokens++ = i;
160 }
161 }
162 }
163
164 mask <<= 1;
165 if (mask == 0)
166 {
167 mask = 1;
168 fp2++;
169 fp1++;
170 }
171 }
172 errp->nerrs = errtokens - errp->errs;
173 if (errp->nerrs)
174 {
175 /* Some tokens have been explicitly made errors. Allocate
176 a permanent errs structure for this state, to record them. */
177 i = (char *) errtokens - (char *) errp;
178 err_table[state] = (errs *) xmalloc ((unsigned int) i);
179 bcopy (errp, err_table[state], i);
180 }
181 else
182 err_table[state] = 0;
183 free (errp);
184 }
185
186
187 static void
188 set_conflicts (int state)
189 {
190 int i;
191 int k;
192 shifts *shiftp;
193 unsigned *fp2;
194 unsigned *fp3;
195 unsigned *fp4;
196 unsigned *fp1;
197 int symbol;
198
199 if (consistent[state])
200 return;
201
202 for (i = 0; i < tokensetsize; i++)
203 lookaheadset[i] = 0;
204
205 shiftp = shift_table[state];
206 if (shiftp)
207 {
208 k = shiftp->nshifts;
209 for (i = 0; i < k; i++)
210 {
211 symbol = accessing_symbol[shiftp->shifts[i]];
212 if (ISVAR (symbol))
213 break;
214 SETBIT (lookaheadset, symbol);
215 }
216 }
217
218 k = lookaheads[state + 1];
219 fp4 = lookaheadset + tokensetsize;
220
221 /* Loop over all rules which require lookahead in this state. First
222 check for shift-reduce conflict, and try to resolve using
223 precedence */
224 for (i = lookaheads[state]; i < k; i++)
225 if (rprec[LAruleno[i]])
226 {
227 fp1 = LA + i * tokensetsize;
228 fp2 = fp1;
229 fp3 = lookaheadset;
230
231 while (fp3 < fp4)
232 {
233 if (*fp2++ & *fp3++)
234 {
235 resolve_sr_conflict (state, i);
236 break;
237 }
238 }
239 }
240
241
242 /* Loop over all rules which require lookahead in this state. Check
243 for conflicts not resolved above. */
244 for (i = lookaheads[state]; i < k; i++)
245 {
246 fp1 = LA + i * tokensetsize;
247 fp2 = fp1;
248 fp3 = lookaheadset;
249
250 while (fp3 < fp4)
251 {
252 if (*fp2++ & *fp3++)
253 {
254 conflicts[state] = 1;
255 any_conflicts = 1;
256 }
257 }
258
259 fp2 = fp1;
260 fp3 = lookaheadset;
261
262 while (fp3 < fp4)
263 *fp3++ |= *fp2++;
264 }
265 }
266
267 void
268 initialize_conflicts (void)
269 {
270 int i;
271
272 conflicts = NEW2 (nstates, char);
273 shiftset = NEW2 (tokensetsize, unsigned);
274 lookaheadset = NEW2 (tokensetsize, unsigned);
275
276 err_table = NEW2 (nstates, errs *);
277
278 any_conflicts = 0;
279
280 for (i = 0; i < nstates; i++)
281 set_conflicts (i);
282 }
283
284
285 /*---------------------------------------------.
286 | Count the number of shift/reduce conflicts. |
287 `---------------------------------------------*/
288
289 static void
290 count_sr_conflicts (int state)
291 {
292 int i;
293 int k;
294 int mask;
295 shifts *shiftp;
296 unsigned *fp1;
297 unsigned *fp2;
298 unsigned *fp3;
299 int symbol;
300
301 src_count = 0;
302
303 shiftp = shift_table[state];
304 if (!shiftp)
305 return;
306
307 for (i = 0; i < tokensetsize; i++)
308 {
309 shiftset[i] = 0;
310 lookaheadset[i] = 0;
311 }
312
313 k = shiftp->nshifts;
314 for (i = 0; i < k; i++)
315 {
316 if (!shiftp->shifts[i])
317 continue;
318 symbol = accessing_symbol[shiftp->shifts[i]];
319 if (ISVAR (symbol))
320 break;
321 SETBIT (shiftset, symbol);
322 }
323
324 k = lookaheads[state + 1];
325 fp3 = lookaheadset + tokensetsize;
326
327 for (i = lookaheads[state]; i < k; i++)
328 {
329 fp1 = LA + i * tokensetsize;
330 fp2 = lookaheadset;
331
332 while (fp2 < fp3)
333 *fp2++ |= *fp1++;
334 }
335
336 fp1 = shiftset;
337 fp2 = lookaheadset;
338
339 while (fp2 < fp3)
340 *fp2++ &= *fp1++;
341
342 mask = 1;
343 fp2 = lookaheadset;
344 for (i = 0; i < ntokens; i++)
345 {
346 if (mask & *fp2)
347 src_count++;
348
349 mask <<= 1;
350 if (mask == 0)
351 {
352 mask = 1;
353 fp2++;
354 }
355 }
356 }
357
358
359 /*----------------------------------------------.
360 | Count the number of reduce/reduce conflicts. |
361 `----------------------------------------------*/
362
363 static void
364 count_rr_conflicts (int state)
365 {
366 int i;
367 int j;
368 int count;
369 unsigned mask;
370 unsigned *baseword;
371 unsigned *wordp;
372 int m;
373 int n;
374
375 rrc_count = 0;
376
377 m = lookaheads[state];
378 n = lookaheads[state + 1];
379
380 if (n - m < 2)
381 return;
382
383 mask = 1;
384 baseword = LA + m * tokensetsize;
385 for (i = 0; i < ntokens; i++)
386 {
387 wordp = baseword;
388
389 count = 0;
390 for (j = m; j < n; j++)
391 {
392 if (mask & *wordp)
393 count++;
394
395 wordp += tokensetsize;
396 }
397
398 if (count >= 2)
399 rrc_count++;
400
401 mask <<= 1;
402 if (mask == 0)
403 {
404 mask = 1;
405 baseword++;
406 }
407 }
408 }
409
410 /*----------------------------------------------------------.
411 | Output to OUT a human readable report on shift/reduce and |
412 | reduce/reduce conflict numbers (SRC_NUM, RRC_NUM). |
413 `----------------------------------------------------------*/
414
415 static void
416 conflict_report (FILE *out, int src_num, int rrc_num)
417 {
418 if (src_num == 1)
419 fprintf (out, _(" 1 shift/reduce conflict"));
420 else if (src_num > 1)
421 fprintf (out, _(" %d shift/reduce conflicts"), src_num);
422
423 if (src_num > 0 && rrc_num > 0)
424 fprintf (out, _(" and"));
425
426 if (rrc_num == 1)
427 fprintf (out, _(" 1 reduce/reduce conflict"));
428 else if (rrc_num > 1)
429 fprintf (out, _(" %d reduce/reduce conflicts"), rrc_num);
430
431 putc ('.', out);
432 putc ('\n', out);
433 }
434
435
436 /*---------------------------------------------.
437 | Compute and give a report on the conflicts. |
438 `---------------------------------------------*/
439
440 void
441 print_conflicts (void)
442 {
443 int i;
444
445 src_total = 0;
446 rrc_total = 0;
447
448 /* Count the total number of conflicts, and if wanted, give a
449 detailed report in FOUTPUT. */
450 for (i = 0; i < nstates; i++)
451 {
452 if (conflicts[i])
453 {
454 count_sr_conflicts (i);
455 count_rr_conflicts (i);
456 src_total += src_count;
457 rrc_total += rrc_count;
458
459 if (verboseflag)
460 {
461 fprintf (foutput, _("State %d contains"), i);
462 conflict_report (foutput, src_count, rrc_count);
463 }
464 }
465 }
466
467 /* Report the total number of conflicts on STDERR. */
468 if (fixed_outfiles)
469 {
470 /* If invoked with `--yacc', use the output format specified by
471 POSIX. */
472 fprintf (stderr, _("conflicts: "));
473 if (src_total > 0)
474 fprintf (stderr, _(" %d shift/reduce"), src_total);
475 if (src_total > 0 && rrc_total > 0)
476 fprintf (stderr, ",");
477 if (rrc_total > 0)
478 fprintf (stderr, _(" %d reduce/reduce"), rrc_total);
479 putc ('\n', stderr);
480 }
481 else
482 {
483 fprintf (stderr, _("%s contains"), infile);
484 conflict_report (stderr, src_total, rrc_total);
485 }
486 }
487
488
489 void
490 print_reductions (int state)
491 {
492 int i;
493 int j;
494 int k;
495 unsigned *fp1;
496 unsigned *fp2;
497 unsigned *fp3;
498 unsigned *fp4;
499 int rule;
500 int symbol;
501 unsigned mask;
502 int m;
503 int n;
504 int default_LA;
505 int default_rule = 0;
506 int cmax;
507 int count;
508 shifts *shiftp;
509 errs *errp;
510 int nodefault = 0;
511
512 for (i = 0; i < tokensetsize; i++)
513 shiftset[i] = 0;
514
515 shiftp = shift_table[state];
516 if (shiftp)
517 {
518 k = shiftp->nshifts;
519 for (i = 0; i < k; i++)
520 {
521 if (!shiftp->shifts[i])
522 continue;
523 symbol = accessing_symbol[shiftp->shifts[i]];
524 if (ISVAR (symbol))
525 break;
526 /* if this state has a shift for the error token,
527 don't use a default rule. */
528 if (symbol == error_token_number)
529 nodefault = 1;
530 SETBIT (shiftset, symbol);
531 }
532 }
533
534 errp = err_table[state];
535 if (errp)
536 {
537 k = errp->nerrs;
538 for (i = 0; i < k; i++)
539 {
540 if (!errp->errs[i])
541 continue;
542 symbol = errp->errs[i];
543 SETBIT (shiftset, symbol);
544 }
545 }
546
547 m = lookaheads[state];
548 n = lookaheads[state + 1];
549
550 if (n - m == 1 && !nodefault)
551 {
552 default_rule = LAruleno[m];
553
554 fp1 = LA + m * tokensetsize;
555 fp2 = shiftset;
556 fp3 = lookaheadset;
557 fp4 = lookaheadset + tokensetsize;
558
559 while (fp3 < fp4)
560 *fp3++ = *fp1++ & *fp2++;
561
562 mask = 1;
563 fp3 = lookaheadset;
564
565 for (i = 0; i < ntokens; i++)
566 {
567 if (mask & *fp3)
568 fprintf (foutput, _(" %-4s\t[reduce using rule %d (%s)]\n"),
569 tags[i], default_rule, tags[rlhs[default_rule]]);
570
571 mask <<= 1;
572 if (mask == 0)
573 {
574 mask = 1;
575 fp3++;
576 }
577 }
578
579 fprintf (foutput, _(" $default\treduce using rule %d (%s)\n\n"),
580 default_rule, tags[rlhs[default_rule]]);
581 }
582 else if (n - m >= 1)
583 {
584 cmax = 0;
585 default_LA = -1;
586 fp4 = lookaheadset + tokensetsize;
587
588 if (!nodefault)
589 for (i = m; i < n; i++)
590 {
591 fp1 = LA + i * tokensetsize;
592 fp2 = shiftset;
593 fp3 = lookaheadset;
594
595 while (fp3 < fp4)
596 *fp3++ = *fp1++ & (~(*fp2++));
597
598 count = 0;
599 mask = 1;
600 fp3 = lookaheadset;
601 for (j = 0; j < ntokens; j++)
602 {
603 if (mask & *fp3)
604 count++;
605
606 mask <<= 1;
607 if (mask == 0)
608 {
609 mask = 1;
610 fp3++;
611 }
612 }
613
614 if (count > cmax)
615 {
616 cmax = count;
617 default_LA = i;
618 default_rule = LAruleno[i];
619 }
620
621 fp2 = shiftset;
622 fp3 = lookaheadset;
623
624 while (fp3 < fp4)
625 *fp2++ |= *fp3++;
626 }
627
628 for (i = 0; i < tokensetsize; i++)
629 shiftset[i] = 0;
630
631 if (shiftp)
632 {
633 k = shiftp->nshifts;
634 for (i = 0; i < k; i++)
635 {
636 if (!shiftp->shifts[i])
637 continue;
638 symbol = accessing_symbol[shiftp->shifts[i]];
639 if (ISVAR (symbol))
640 break;
641 SETBIT (shiftset, symbol);
642 }
643 }
644
645 mask = 1;
646 fp1 = LA + m * tokensetsize;
647 fp2 = shiftset;
648 for (i = 0; i < ntokens; i++)
649 {
650 int defaulted = 0;
651
652 if (mask & *fp2)
653 count = 1;
654 else
655 count = 0;
656
657 fp3 = fp1;
658 for (j = m; j < n; j++)
659 {
660 if (mask & *fp3)
661 {
662 if (count == 0)
663 {
664 if (j != default_LA)
665 {
666 rule = LAruleno[j];
667 fprintf (foutput,
668 _(" %-4s\treduce using rule %d (%s)\n"),
669 tags[i], rule, tags[rlhs[rule]]);
670 }
671 else
672 defaulted = 1;
673
674 count++;
675 }
676 else
677 {
678 if (defaulted)
679 {
680 rule = LAruleno[default_LA];
681 fprintf (foutput,
682 _(" %-4s\treduce using rule %d (%s)\n"),
683 tags[i], rule, tags[rlhs[rule]]);
684 defaulted = 0;
685 }
686 rule = LAruleno[j];
687 fprintf (foutput,
688 _(" %-4s\t[reduce using rule %d (%s)]\n"),
689 tags[i], rule, tags[rlhs[rule]]);
690 }
691 }
692
693 fp3 += tokensetsize;
694 }
695
696 mask <<= 1;
697 if (mask == 0)
698 {
699 mask = 1;
700 /* We tried incrementing just fp1, and just fp2; both seem wrong.
701 It seems necessary to increment both in sync. */
702 fp1++;
703 fp2++;
704 }
705 }
706
707 if (default_LA >= 0)
708 {
709 fprintf (foutput, _(" $default\treduce using rule %d (%s)\n"),
710 default_rule, tags[rlhs[default_rule]]);
711 }
712
713 putc ('\n', foutput);
714 }
715 }
716
717
718 void
719 finalize_conflicts (void)
720 {
721 FREE (conflicts);
722 FREE (shiftset);
723 FREE (lookaheadset);
724 }