]> git.saurik.com Git - bison.git/blob - src/conflicts.c
maint: more syntax-checks
[bison.git] / src / conflicts.c
1 /* Find and resolve or report lookahead conflicts for bison,
2
3 Copyright (C) 1984, 1989, 1992, 2000-2012 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 log_resolution (redrule, i, reduce_resolution);
280 flush_shift (s, i);
281 }
282 else if (symbols[i]->prec > redprec)
283 {
284 log_resolution (redrule, i, shift_resolution);
285 flush_reduce (lookahead_tokens, i);
286 }
287 else
288 /* Matching precedence levels.
289 For non-defined associativity, keep both: unexpected
290 associativity conflict.
291 For left associativity, keep only the reduction.
292 For right associativity, keep only the shift.
293 For nonassociativity, keep neither. */
294
295 switch (symbols[i]->assoc)
296 {
297 case undef_assoc:
298 abort ();
299
300 case precedence_assoc:
301 break;
302
303 case right_assoc:
304 log_resolution (redrule, i, right_resolution);
305 flush_reduce (lookahead_tokens, i);
306 break;
307
308 case left_assoc:
309 log_resolution (redrule, i, left_resolution);
310 flush_shift (s, i);
311 break;
312
313 case non_assoc:
314 log_resolution (redrule, i, nonassoc_resolution);
315 flush_shift (s, i);
316 flush_reduce (lookahead_tokens, i);
317 /* Record an explicit error for this token. */
318 errors[(*nerrs)++] = symbols[i];
319 break;
320 }
321 }
322 }
323
324
325 /*-------------------------------------------------------------------.
326 | Solve the S/R conflicts of state S using the |
327 | precedence/associativity, and flag it inconsistent if it still has |
328 | conflicts. ERRORS can be used as storage to compute the list of |
329 | lookahead tokens on which S raises a syntax error (%nonassoc). |
330 `-------------------------------------------------------------------*/
331
332 static void
333 set_conflicts (state *s, symbol **errors)
334 {
335 int i;
336 transitions *trans = s->transitions;
337 reductions *reds = s->reductions;
338 int nerrs = 0;
339
340 if (s->consistent)
341 return;
342
343 bitset_zero (lookahead_set);
344
345 FOR_EACH_SHIFT (trans, i)
346 bitset_set (lookahead_set, TRANSITION_SYMBOL (trans, i));
347
348 /* Loop over all rules which require lookahead in this state. First
349 check for shift-reduce conflict, and try to resolve using
350 precedence. */
351 for (i = 0; i < reds->num; ++i)
352 if (reds->rules[i]->prec && reds->rules[i]->prec->prec
353 && !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
354 resolve_sr_conflict (s, i, errors, &nerrs);
355
356 if (nerrs)
357 {
358 /* Some tokens have been explicitly made errors. Allocate a
359 permanent errs structure for this state, to record them. */
360 state_errs_set (s, nerrs, errors);
361 }
362 if (obstack_object_size (&solved_conflicts_obstack))
363 s->solved_conflicts = obstack_finish0 (&solved_conflicts_obstack);
364 if (obstack_object_size (&solved_conflicts_xml_obstack))
365 s->solved_conflicts_xml = obstack_finish0 (&solved_conflicts_xml_obstack);
366
367 /* Loop over all rules which require lookahead in this state. Check
368 for conflicts not resolved above. */
369 for (i = 0; i < reds->num; ++i)
370 {
371 if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
372 conflicts[s->number] = 1;
373 bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
374 }
375 }
376
377
378 /*----------------------------------------------------------------.
379 | Solve all the S/R conflicts using the precedence/associativity, |
380 | and flag as inconsistent the states that still have conflicts. |
381 `----------------------------------------------------------------*/
382
383 void
384 conflicts_solve (void)
385 {
386 state_number i;
387 /* List of lookahead tokens on which we explicitly raise a syntax error. */
388 symbol **errors = xnmalloc (ntokens + 1, sizeof *errors);
389
390 conflicts = xcalloc (nstates, sizeof *conflicts);
391 shift_set = bitset_create (ntokens, BITSET_FIXED);
392 lookahead_set = bitset_create (ntokens, BITSET_FIXED);
393 obstack_init (&solved_conflicts_obstack);
394 obstack_init (&solved_conflicts_xml_obstack);
395
396 for (i = 0; i < nstates; i++)
397 {
398 set_conflicts (states[i], errors);
399
400 /* For uniformity of the code, make sure all the states have a valid
401 `errs' member. */
402 if (!states[i]->errs)
403 states[i]->errs = errs_new (0, 0);
404 }
405
406 free (errors);
407 }
408
409
410 void
411 conflicts_update_state_numbers (state_number old_to_new[],
412 state_number nstates_old)
413 {
414 state_number i;
415 for (i = 0; i < nstates_old; ++i)
416 if (old_to_new[i] != nstates_old)
417 conflicts[old_to_new[i]] = conflicts[i];
418 }
419
420
421 /*---------------------------------------------.
422 | Count the number of shift/reduce conflicts. |
423 `---------------------------------------------*/
424
425 static size_t
426 count_state_sr_conflicts (state *s)
427 {
428 int i;
429 transitions *trans = s->transitions;
430 reductions *reds = s->reductions;
431
432 if (!trans)
433 return 0;
434
435 bitset_zero (lookahead_set);
436 bitset_zero (shift_set);
437
438 FOR_EACH_SHIFT (trans, i)
439 bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
440
441 for (i = 0; i < reds->num; ++i)
442 bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
443
444 bitset_and (lookahead_set, lookahead_set, shift_set);
445
446 return bitset_count (lookahead_set);
447 }
448
449 /*---------------------------------------------.
450 | The total number of shift/reduce conflicts. |
451 `---------------------------------------------*/
452
453 static size_t
454 count_sr_conflicts (void)
455 {
456 size_t res = 0;
457 state_number i;
458
459 /* Conflicts by state. */
460 for (i = 0; i < nstates; i++)
461 if (conflicts[i])
462 res += count_state_sr_conflicts (states[i]);
463 return res;
464 }
465
466
467
468 /*----------------------------------------------------------------.
469 | Count the number of reduce/reduce conflicts. If ONE_PER_TOKEN, |
470 | count one conflict for each token that has any reduce/reduce |
471 | conflicts. Otherwise, count one conflict for each pair of |
472 | conflicting reductions. |
473 `----------------------------------------------------------------*/
474
475 static size_t
476 count_state_rr_conflicts (state *s, bool one_per_token)
477 {
478 int i;
479 reductions *reds = s->reductions;
480 size_t res = 0;
481
482 for (i = 0; i < ntokens; i++)
483 {
484 int count = 0;
485 int j;
486 for (j = 0; j < reds->num; ++j)
487 count += bitset_test (reds->lookahead_tokens[j], i);
488 if (count >= 2)
489 res += one_per_token ? 1 : count-1;
490 }
491
492 return res;
493 }
494
495 static size_t
496 count_rr_conflicts (bool one_per_token)
497 {
498 size_t res = 0;
499 state_number i;
500
501 /* Conflicts by state. */
502 for (i = 0; i < nstates; i++)
503 if (conflicts[i])
504 res += count_state_rr_conflicts (states[i], one_per_token);
505 return res;
506 }
507
508
509 /*-----------------------------------------------------------.
510 | Output the detailed description of states with conflicts. |
511 `-----------------------------------------------------------*/
512
513 void
514 conflicts_output (FILE *out)
515 {
516 bool printed_sth = false;
517 state_number i;
518 for (i = 0; i < nstates; i++)
519 {
520 state *s = states[i];
521 if (conflicts[i])
522 {
523 int src = count_state_sr_conflicts (s);
524 int rrc = count_state_rr_conflicts (s, true);
525 fprintf (out, _("State %d "), i);
526 if (src && rrc)
527 fprintf (out,
528 _("conflicts: %d shift/reduce, %d reduce/reduce\n"),
529 src, rrc);
530 else if (src)
531 fprintf (out, _("conflicts: %d shift/reduce\n"), src);
532 else if (rrc)
533 fprintf (out, _("conflicts: %d reduce/reduce\n"), rrc);
534 printed_sth = true;
535 }
536 }
537 if (printed_sth)
538 fputs ("\n\n", out);
539 }
540
541 /*--------------------------------------------------------.
542 | Total the number of S/R and R/R conflicts. Unlike the |
543 | code in conflicts_output, however, count EACH pair of |
544 | reductions for the same state and lookahead as one |
545 | conflict. |
546 `--------------------------------------------------------*/
547
548 int
549 conflicts_total_count (void)
550 {
551 return count_sr_conflicts () + count_rr_conflicts (false);
552 }
553
554
555 /*------------------------------------------.
556 | Reporting the total number of conflicts. |
557 `------------------------------------------*/
558
559 void
560 conflicts_print (void)
561 {
562 if (! glr_parser && expected_rr_conflicts != -1)
563 {
564 complain (NULL, Wother, _("%%expect-rr applies only to GLR parsers"));
565 expected_rr_conflicts = -1;
566 }
567
568 /* Screams for factoring, but almost useless because of the
569 different strings to translate. */
570 {
571 int total = count_sr_conflicts ();
572 // If %expect is not used, but %expect-rr is, then expect 0 sr.
573 int expected =
574 (expected_sr_conflicts == -1 && expected_rr_conflicts != -1)
575 ? 0
576 : expected_sr_conflicts;
577 if (expected != -1)
578 {
579 if (expected != total)
580 complain (NULL, complaint,
581 _("shift/reduce conflicts: %d found, %d expected"),
582 total, expected);
583 }
584 else if (total)
585 complain (NULL, Wconflicts_sr,
586 ngettext ("%d shift/reduce conflict",
587 "%d shift/reduce conflicts",
588 total),
589 total);
590 }
591
592 {
593 int total = count_rr_conflicts (true);
594 // If %expect-rr is not used, but %expect is, then expect 0 rr.
595 int expected =
596 (expected_rr_conflicts == -1 && expected_sr_conflicts != -1)
597 ? 0
598 : expected_rr_conflicts;
599 if (expected != -1)
600 {
601 if (expected != total)
602 complain (NULL, complaint,
603 _("reduce/reduce conflicts: %d found, %d expected"),
604 total, expected);
605 }
606 else if (total)
607 complain (NULL, Wconflicts_rr,
608 ngettext ("%d reduce/reduce conflict",
609 "%d reduce/reduce conflicts",
610 total),
611 total);
612 }
613 }
614
615
616 void
617 conflicts_free (void)
618 {
619 free (conflicts);
620 bitset_free (shift_set);
621 bitset_free (lookahead_set);
622 obstack_free (&solved_conflicts_obstack, NULL);
623 obstack_free (&solved_conflicts_xml_obstack, NULL);
624 }