]> git.saurik.com Git - bison.git/blob - src/conflicts.c
NEWS: prepare for 2.7.91
[bison.git] / src / conflicts.c
1 /* Find and resolve or report lookahead conflicts for bison,
2
3 Copyright (C) 1984, 1989, 1992, 2000-2013 Free Software Foundation,
4 Inc.
5
6 This file is part of Bison, the GNU Compiler Compiler.
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21 #include <config.h>
22 #include "system.h"
23
24 #include <bitset.h>
25
26 #include "LR0.h"
27 #include "complain.h"
28 #include "conflicts.h"
29 #include "files.h"
30 #include "getargs.h"
31 #include "gram.h"
32 #include "lalr.h"
33 #include "print-xml.h"
34 #include "reader.h"
35 #include "state.h"
36 #include "symtab.h"
37
38 /* -1 stands for not specified. */
39 int expected_sr_conflicts = -1;
40 int expected_rr_conflicts = -1;
41 static char *conflicts;
42 static struct obstack solved_conflicts_obstack;
43 static struct obstack solved_conflicts_xml_obstack;
44
45 static bitset shift_set;
46 static bitset lookahead_set;
47
48 \f
49
50 enum conflict_resolution
51 {
52 shift_resolution,
53 reduce_resolution,
54 left_resolution,
55 right_resolution,
56 nonassoc_resolution
57 };
58
59
60 /*----------------------------------------------------------------.
61 | Explain how an SR conflict between TOKEN and RULE was resolved: |
62 | RESOLUTION. |
63 `----------------------------------------------------------------*/
64
65 static inline void
66 log_resolution (rule *r, symbol_number token,
67 enum conflict_resolution resolution)
68 {
69 if (report_flag & report_solved_conflicts)
70 {
71 /* The description of the resolution. */
72 switch (resolution)
73 {
74 case shift_resolution:
75 case right_resolution:
76 obstack_printf (&solved_conflicts_obstack,
77 _(" Conflict between rule %d and token %s"
78 " resolved as shift"),
79 r->number,
80 symbols[token]->tag);
81 break;
82
83 case reduce_resolution:
84 case left_resolution:
85 obstack_printf (&solved_conflicts_obstack,
86 _(" Conflict between rule %d and token %s"
87 " resolved as reduce"),
88 r->number,
89 symbols[token]->tag);
90 break;
91
92 case nonassoc_resolution:
93 obstack_printf (&solved_conflicts_obstack,
94 _(" Conflict between rule %d and token %s"
95 " resolved as an error"),
96 r->number,
97 symbols[token]->tag);
98 break;
99 }
100
101 /* The reason. */
102 switch (resolution)
103 {
104 case shift_resolution:
105 obstack_printf (&solved_conflicts_obstack,
106 " (%s < %s)",
107 r->prec->tag,
108 symbols[token]->tag);
109 break;
110
111 case reduce_resolution:
112 obstack_printf (&solved_conflicts_obstack,
113 " (%s < %s)",
114 symbols[token]->tag,
115 r->prec->tag);
116 break;
117
118 case left_resolution:
119 obstack_printf (&solved_conflicts_obstack,
120 " (%%left %s)",
121 symbols[token]->tag);
122 break;
123
124 case right_resolution:
125 obstack_printf (&solved_conflicts_obstack,
126 " (%%right %s)",
127 symbols[token]->tag);
128 break;
129
130 case nonassoc_resolution:
131 obstack_printf (&solved_conflicts_obstack,
132 " (%%nonassoc %s)",
133 symbols[token]->tag);
134 break;
135 }
136
137 obstack_sgrow (&solved_conflicts_obstack, ".\n");
138 }
139
140 /* XML report */
141 if (xml_flag)
142 {
143 /* The description of the resolution. */
144 switch (resolution)
145 {
146 case shift_resolution:
147 case right_resolution:
148 obstack_printf (&solved_conflicts_xml_obstack,
149 " <resolution rule=\"%d\" symbol=\"%s\""
150 " type=\"shift\">",
151 r->number,
152 xml_escape (symbols[token]->tag));
153 break;
154
155 case reduce_resolution:
156 case left_resolution:
157 obstack_printf (&solved_conflicts_xml_obstack,
158 " <resolution rule=\"%d\" symbol=\"%s\""
159 " type=\"reduce\">",
160 r->number,
161 xml_escape (symbols[token]->tag));
162 break;
163
164 case nonassoc_resolution:
165 obstack_printf (&solved_conflicts_xml_obstack,
166 " <resolution rule=\"%d\" symbol=\"%s\""
167 " type=\"error\">",
168 r->number,
169 xml_escape (symbols[token]->tag));
170 break;
171 }
172
173 /* The reason. */
174 switch (resolution)
175 {
176 case shift_resolution:
177 obstack_printf (&solved_conflicts_xml_obstack,
178 "%s &lt; %s",
179 xml_escape_n (0, r->prec->tag),
180 xml_escape_n (1, symbols[token]->tag));
181 break;
182
183 case reduce_resolution:
184 obstack_printf (&solved_conflicts_xml_obstack,
185 "%s &lt; %s",
186 xml_escape_n (0, symbols[token]->tag),
187 xml_escape_n (1, r->prec->tag));
188 break;
189
190 case left_resolution:
191 obstack_printf (&solved_conflicts_xml_obstack,
192 "%%left %s",
193 xml_escape (symbols[token]->tag));
194 break;
195
196 case right_resolution:
197 obstack_printf (&solved_conflicts_xml_obstack,
198 "%%right %s",
199 xml_escape (symbols[token]->tag));
200 break;
201
202 case nonassoc_resolution:
203 obstack_printf (&solved_conflicts_xml_obstack,
204 "%%nonassoc %s",
205 xml_escape (symbols[token]->tag));
206 break;
207 }
208
209 obstack_sgrow (&solved_conflicts_xml_obstack, "</resolution>\n");
210 }
211 }
212
213
214 /*------------------------------------------------------------------.
215 | Turn off the shift recorded for the specified token in the |
216 | specified state. Used when we resolve a shift-reduce conflict in |
217 | favor of the reduction or as an error (%nonassoc). |
218 `------------------------------------------------------------------*/
219
220 static void
221 flush_shift (state *s, int token)
222 {
223 transitions *trans = s->transitions;
224 int i;
225
226 bitset_reset (lookahead_set, token);
227 for (i = 0; i < trans->num; i++)
228 if (!TRANSITION_IS_DISABLED (trans, i)
229 && TRANSITION_SYMBOL (trans, i) == token)
230 TRANSITION_DISABLE (trans, i);
231 }
232
233
234 /*--------------------------------------------------------------------.
235 | Turn off the reduce recorded for the specified token in the |
236 | specified lookahead set. Used when we resolve a shift-reduce |
237 | conflict in favor of the shift or as an error (%nonassoc). |
238 `--------------------------------------------------------------------*/
239
240 static void
241 flush_reduce (bitset lookahead_tokens, int token)
242 {
243 bitset_reset (lookahead_tokens, token);
244 }
245
246
247 /*------------------------------------------------------------------.
248 | Attempt to resolve shift-reduce conflict for one rule by means of |
249 | precedence declarations. It has already been checked that the |
250 | rule has a precedence. A conflict is resolved by modifying the |
251 | shift or reduce tables so that there is no longer a conflict. |
252 | |
253 | RULENO is the number of the lookahead bitset to consider. |
254 | |
255 | ERRORS and NERRS can be used to store discovered explicit |
256 | errors. |
257 `------------------------------------------------------------------*/
258
259 static void
260 resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
261 {
262 symbol_number i;
263 reductions *reds = s->reductions;
264 /* Find the rule to reduce by to get precedence of reduction. */
265 rule *redrule = reds->rules[ruleno];
266 int redprec = redrule->prec->prec;
267 bitset lookahead_tokens = reds->lookahead_tokens[ruleno];
268
269 for (i = 0; i < ntokens; i++)
270 if (bitset_test (lookahead_tokens, i)
271 && bitset_test (lookahead_set, i)
272 && symbols[i]->prec)
273 {
274 /* Shift-reduce conflict occurs for token number i
275 and it has a precedence.
276 The precedence of shifting is that of token i. */
277 if (symbols[i]->prec < redprec)
278 {
279 register_precedence (redrule->prec->number, i);
280 log_resolution (redrule, i, reduce_resolution);
281 flush_shift (s, i);
282 }
283 else if (symbols[i]->prec > redprec)
284 {
285 register_precedence (i, redrule->prec->number);
286 log_resolution (redrule, i, shift_resolution);
287 flush_reduce (lookahead_tokens, i);
288 }
289 else
290 /* Matching precedence levels.
291 For non-defined associativity, keep both: unexpected
292 associativity conflict.
293 For left associativity, keep only the reduction.
294 For right associativity, keep only the shift.
295 For nonassociativity, keep neither. */
296
297 switch (symbols[i]->assoc)
298 {
299 case undef_assoc:
300 abort ();
301
302 case precedence_assoc:
303 break;
304
305 case right_assoc:
306 register_assoc (i, redrule->prec->number);
307 log_resolution (redrule, i, right_resolution);
308 flush_reduce (lookahead_tokens, i);
309 break;
310
311 case left_assoc:
312 register_assoc (i, redrule->prec->number);
313 log_resolution (redrule, i, left_resolution);
314 flush_shift (s, i);
315 break;
316
317 case non_assoc:
318 register_assoc (i, redrule->prec->number);
319 log_resolution (redrule, i, nonassoc_resolution);
320 flush_shift (s, i);
321 flush_reduce (lookahead_tokens, i);
322 /* Record an explicit error for this token. */
323 errors[(*nerrs)++] = symbols[i];
324 break;
325 }
326 }
327 }
328
329
330 /*-------------------------------------------------------------------.
331 | Solve the S/R conflicts of state S using the |
332 | precedence/associativity, and flag it inconsistent if it still has |
333 | conflicts. ERRORS can be used as storage to compute the list of |
334 | lookahead tokens on which S raises a syntax error (%nonassoc). |
335 `-------------------------------------------------------------------*/
336
337 static void
338 set_conflicts (state *s, symbol **errors)
339 {
340 int i;
341 transitions *trans = s->transitions;
342 reductions *reds = s->reductions;
343 int nerrs = 0;
344
345 if (s->consistent)
346 return;
347
348 bitset_zero (lookahead_set);
349
350 FOR_EACH_SHIFT (trans, i)
351 bitset_set (lookahead_set, TRANSITION_SYMBOL (trans, i));
352
353 /* Loop over all rules which require lookahead in this state. First
354 check for shift-reduce conflict, and try to resolve using
355 precedence. */
356 for (i = 0; i < reds->num; ++i)
357 if (reds->rules[i]->prec && reds->rules[i]->prec->prec
358 && !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
359 resolve_sr_conflict (s, i, errors, &nerrs);
360
361 if (nerrs)
362 {
363 /* Some tokens have been explicitly made errors. Allocate a
364 permanent errs structure for this state, to record them. */
365 state_errs_set (s, nerrs, errors);
366 }
367 if (obstack_object_size (&solved_conflicts_obstack))
368 s->solved_conflicts = obstack_finish0 (&solved_conflicts_obstack);
369 if (obstack_object_size (&solved_conflicts_xml_obstack))
370 s->solved_conflicts_xml = obstack_finish0 (&solved_conflicts_xml_obstack);
371
372 /* Loop over all rules which require lookahead in this state. Check
373 for conflicts not resolved above. */
374 for (i = 0; i < reds->num; ++i)
375 {
376 if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
377 conflicts[s->number] = 1;
378 bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
379 }
380 }
381
382
383 /*----------------------------------------------------------------.
384 | Solve all the S/R conflicts using the precedence/associativity, |
385 | and flag as inconsistent the states that still have conflicts. |
386 `----------------------------------------------------------------*/
387
388 void
389 conflicts_solve (void)
390 {
391 state_number i;
392 /* List of lookahead tokens on which we explicitly raise a syntax error. */
393 symbol **errors = xnmalloc (ntokens + 1, sizeof *errors);
394
395 conflicts = xcalloc (nstates, sizeof *conflicts);
396 shift_set = bitset_create (ntokens, BITSET_FIXED);
397 lookahead_set = bitset_create (ntokens, BITSET_FIXED);
398 obstack_init (&solved_conflicts_obstack);
399 obstack_init (&solved_conflicts_xml_obstack);
400
401 for (i = 0; i < nstates; i++)
402 {
403 set_conflicts (states[i], errors);
404
405 /* For uniformity of the code, make sure all the states have a valid
406 'errs' member. */
407 if (!states[i]->errs)
408 states[i]->errs = errs_new (0, 0);
409 }
410
411 free (errors);
412 }
413
414
415 void
416 conflicts_update_state_numbers (state_number old_to_new[],
417 state_number nstates_old)
418 {
419 state_number i;
420 for (i = 0; i < nstates_old; ++i)
421 if (old_to_new[i] != nstates_old)
422 conflicts[old_to_new[i]] = conflicts[i];
423 }
424
425
426 /*---------------------------------------------.
427 | Count the number of shift/reduce conflicts. |
428 `---------------------------------------------*/
429
430 static size_t
431 count_state_sr_conflicts (state *s)
432 {
433 int i;
434 transitions *trans = s->transitions;
435 reductions *reds = s->reductions;
436
437 if (!trans)
438 return 0;
439
440 bitset_zero (lookahead_set);
441 bitset_zero (shift_set);
442
443 FOR_EACH_SHIFT (trans, i)
444 bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
445
446 for (i = 0; i < reds->num; ++i)
447 bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
448
449 bitset_and (lookahead_set, lookahead_set, shift_set);
450
451 return bitset_count (lookahead_set);
452 }
453
454 /*---------------------------------------------.
455 | The total number of shift/reduce conflicts. |
456 `---------------------------------------------*/
457
458 static size_t
459 count_sr_conflicts (void)
460 {
461 size_t res = 0;
462 state_number i;
463
464 /* Conflicts by state. */
465 for (i = 0; i < nstates; i++)
466 if (conflicts[i])
467 res += count_state_sr_conflicts (states[i]);
468 return res;
469 }
470
471
472
473 /*----------------------------------------------------------------.
474 | Count the number of reduce/reduce conflicts. If ONE_PER_TOKEN, |
475 | count one conflict for each token that has any reduce/reduce |
476 | conflicts. Otherwise, count one conflict for each pair of |
477 | conflicting reductions. |
478 `----------------------------------------------------------------*/
479
480 static size_t
481 count_state_rr_conflicts (state *s, bool one_per_token)
482 {
483 int i;
484 reductions *reds = s->reductions;
485 size_t res = 0;
486
487 for (i = 0; i < ntokens; i++)
488 {
489 int count = 0;
490 int j;
491 for (j = 0; j < reds->num; ++j)
492 count += bitset_test (reds->lookahead_tokens[j], i);
493 if (count >= 2)
494 res += one_per_token ? 1 : count-1;
495 }
496
497 return res;
498 }
499
500 static size_t
501 count_rr_conflicts (bool one_per_token)
502 {
503 size_t res = 0;
504 state_number i;
505
506 /* Conflicts by state. */
507 for (i = 0; i < nstates; i++)
508 if (conflicts[i])
509 res += count_state_rr_conflicts (states[i], one_per_token);
510 return res;
511 }
512
513
514 /*-----------------------------------------------------------.
515 | Output the detailed description of states with conflicts. |
516 `-----------------------------------------------------------*/
517
518 void
519 conflicts_output (FILE *out)
520 {
521 bool printed_sth = false;
522 state_number i;
523 for (i = 0; i < nstates; i++)
524 {
525 state *s = states[i];
526 if (conflicts[i])
527 {
528 int src = count_state_sr_conflicts (s);
529 int rrc = count_state_rr_conflicts (s, true);
530 fprintf (out, _("State %d "), i);
531 if (src && rrc)
532 fprintf (out,
533 _("conflicts: %d shift/reduce, %d reduce/reduce\n"),
534 src, rrc);
535 else if (src)
536 fprintf (out, _("conflicts: %d shift/reduce\n"), src);
537 else if (rrc)
538 fprintf (out, _("conflicts: %d reduce/reduce\n"), rrc);
539 printed_sth = true;
540 }
541 }
542 if (printed_sth)
543 fputs ("\n\n", out);
544 }
545
546 /*--------------------------------------------------------.
547 | Total the number of S/R and R/R conflicts. Unlike the |
548 | code in conflicts_output, however, count EACH pair of |
549 | reductions for the same state and lookahead as one |
550 | conflict. |
551 `--------------------------------------------------------*/
552
553 int
554 conflicts_total_count (void)
555 {
556 return count_sr_conflicts () + count_rr_conflicts (false);
557 }
558
559
560 /*------------------------------------------.
561 | Reporting the total number of conflicts. |
562 `------------------------------------------*/
563
564 void
565 conflicts_print (void)
566 {
567 if (! glr_parser && expected_rr_conflicts != -1)
568 {
569 complain (NULL, Wother, _("%%expect-rr applies only to GLR parsers"));
570 expected_rr_conflicts = -1;
571 }
572
573 /* Screams for factoring, but almost useless because of the
574 different strings to translate. */
575 {
576 int total = count_sr_conflicts ();
577 /* If %expect is not used, but %expect-rr is, then expect 0 sr. */
578 int expected =
579 (expected_sr_conflicts == -1 && expected_rr_conflicts != -1)
580 ? 0
581 : expected_sr_conflicts;
582 if (expected != -1)
583 {
584 if (expected != total)
585 complain (NULL, complaint,
586 _("shift/reduce conflicts: %d found, %d expected"),
587 total, expected);
588 }
589 else if (total)
590 complain (NULL, Wconflicts_sr,
591 ngettext ("%d shift/reduce conflict",
592 "%d shift/reduce conflicts",
593 total),
594 total);
595 }
596
597 {
598 int total = count_rr_conflicts (true);
599 /* If %expect-rr is not used, but %expect is, then expect 0 rr. */
600 int expected =
601 (expected_rr_conflicts == -1 && expected_sr_conflicts != -1)
602 ? 0
603 : expected_rr_conflicts;
604 if (expected != -1)
605 {
606 if (expected != total)
607 complain (NULL, complaint,
608 _("reduce/reduce conflicts: %d found, %d expected"),
609 total, expected);
610 }
611 else if (total)
612 complain (NULL, Wconflicts_rr,
613 ngettext ("%d reduce/reduce conflict",
614 "%d reduce/reduce conflicts",
615 total),
616 total);
617 }
618 }
619
620
621 void
622 conflicts_free (void)
623 {
624 free (conflicts);
625 bitset_free (shift_set);
626 bitset_free (lookahead_set);
627 obstack_free (&solved_conflicts_obstack, NULL);
628 obstack_free (&solved_conflicts_xml_obstack, NULL);
629 }