]> git.saurik.com Git - bison.git/blame - src/conflicts.c
Improve handling of multiple S/R conflicts in the same state and of S/R
[bison.git] / src / conflicts.c
CommitLineData
742e4900 1/* Find and resolve or report lookahead conflicts for bison,
f041e30b 2
75ad86ee
JD
3 Copyright (C) 1984, 1989, 1992, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4 2007 Free Software Foundation, Inc.
08089d5d 5
ceed8467 6 This file is part of Bison, the GNU Compiler Compiler.
08089d5d 7
ceed8467
AD
8 Bison is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
08089d5d 12
ceed8467
AD
13 Bison is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
08089d5d 17
ceed8467
AD
18 You should have received a copy of the GNU General Public License
19 along with Bison; see the file COPYING. If not, write to the Free
0fb669f9
PE
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA. */
08089d5d 22
2cec9080 23#include <config.h>
08089d5d 24#include "system.h"
f041e30b
PE
25
26#include <bitset.h>
27
28#include "LR0.h"
7da99ede 29#include "complain.h"
f041e30b 30#include "conflicts.h"
08089d5d 31#include "files.h"
f041e30b 32#include "getargs.h"
08089d5d 33#include "gram.h"
720d742f 34#include "lalr.h"
b2ca4022 35#include "reader.h"
f041e30b
PE
36#include "state.h"
37#include "symtab.h"
d2729d44 38
7da99ede 39/* -1 stands for not specified. */
d6328241
PH
40int expected_sr_conflicts = -1;
41int expected_rr_conflicts = -1;
da2a7671 42static char *conflicts;
d6b771c3 43static struct obstack solved_conflicts_obstack;
08089d5d 44
8dd162d3 45static bitset shift_set;
742e4900 46static bitset lookahead_set;
b408954b 47
c29240e7 48\f
08089d5d 49
f041e30b 50enum conflict_resolution
b408954b
AD
51 {
52 shift_resolution,
53 reduce_resolution,
54 left_resolution,
55 right_resolution,
86eff183 56 nonassoc_resolution
b408954b
AD
57 };
58
59
9801d40c
AD
60/*----------------------------------------------------------------.
61| Explain how an SR conflict between TOKEN and RULE was resolved: |
62| RESOLUTION. |
63`----------------------------------------------------------------*/
64
c29240e7 65static inline void
f041e30b
PE
66log_resolution (rule *r, symbol_number token,
67 enum conflict_resolution resolution)
08089d5d 68{
b408954b
AD
69 if (report_flag & report_solved_conflicts)
70 {
71 /* The description of the resolution. */
72 switch (resolution)
73 {
74 case shift_resolution:
4b3d3a8e 75 case right_resolution:
b408954b
AD
76 obstack_fgrow2 (&solved_conflicts_obstack,
77 _("\
78 Conflict between rule %d and token %s resolved as shift"),
f041e30b 79 r->number,
b408954b
AD
80 symbols[token]->tag);
81 break;
82 case reduce_resolution:
4b3d3a8e 83 case left_resolution:
b408954b
AD
84 obstack_fgrow2 (&solved_conflicts_obstack,
85 _("\
86 Conflict between rule %d and token %s resolved as reduce"),
f041e30b 87 r->number,
b408954b
AD
88 symbols[token]->tag);
89 break;
90 case nonassoc_resolution:
91 obstack_fgrow2 (&solved_conflicts_obstack,
92 _("\
93 Conflict between rule %d and token %s resolved as an error"),
f041e30b 94 r->number,
b408954b
AD
95 symbols[token]->tag);
96 break;
97 }
98
99 /* The reason. */
100 switch (resolution)
101 {
102 case shift_resolution:
103 obstack_fgrow2 (&solved_conflicts_obstack,
104 " (%s < %s)",
f041e30b 105 r->prec->tag,
b408954b
AD
106 symbols[token]->tag);
107 break;
108
109 case reduce_resolution:
110 obstack_fgrow2 (&solved_conflicts_obstack,
111 " (%s < %s)",
112 symbols[token]->tag,
f041e30b 113 r->prec->tag);
b408954b
AD
114 break;
115
116 case left_resolution:
4a713ec2 117 obstack_fgrow1 (&solved_conflicts_obstack,
b408954b
AD
118 " (%%left %s)",
119 symbols[token]->tag);
120 break;
121
122 case right_resolution:
123 obstack_fgrow1 (&solved_conflicts_obstack,
124 " (%%right %s)",
125 symbols[token]->tag);
126 break;
127 case nonassoc_resolution:
128 obstack_fgrow1 (&solved_conflicts_obstack,
129 " (%%nonassoc %s)",
130 symbols[token]->tag);
131 break;
132 }
133 obstack_sgrow (&solved_conflicts_obstack, ".\n");
134 }
08089d5d
DM
135}
136
137
c29240e7
AD
138/*------------------------------------------------------------------.
139| Turn off the shift recorded for the specified token in the |
140| specified state. Used when we resolve a shift-reduce conflict in |
9d774aff 141| favor of the reduction or as an error (%nonassoc). |
c29240e7
AD
142`------------------------------------------------------------------*/
143
4a120d45 144static void
f041e30b 145flush_shift (state *s, int token)
08089d5d 146{
f041e30b 147 transitions *trans = s->transitions;
9f136c07 148 int i;
c29240e7 149
742e4900 150 bitset_reset (lookahead_set, token);
f041e30b
PE
151 for (i = 0; i < trans->num; i++)
152 if (!TRANSITION_IS_DISABLED (trans, i)
153 && TRANSITION_SYMBOL (trans, i) == token)
154 TRANSITION_DISABLE (trans, i);
08089d5d
DM
155}
156
157
8dd162d3 158/*--------------------------------------------------------------------.
9d774aff
JD
159| Turn off the reduce recorded for the specified token in the |
160| specified lookahead set. Used when we resolve a shift-reduce |
161| conflict in favor of the shift or as an error (%nonassoc). |
8dd162d3 162`--------------------------------------------------------------------*/
709ae8c6
AD
163
164static void
742e4900 165flush_reduce (bitset lookahead_tokens, int token)
709ae8c6 166{
742e4900 167 bitset_reset (lookahead_tokens, token);
709ae8c6
AD
168}
169
170
c29240e7
AD
171/*------------------------------------------------------------------.
172| Attempt to resolve shift-reduce conflict for one rule by means of |
173| precedence declarations. It has already been checked that the |
174| rule has a precedence. A conflict is resolved by modifying the |
175| shift or reduce tables so that there is no longer a conflict. |
9801d40c 176| |
742e4900 177| RULENO is the number of the lookahead bitset to consider. |
8b752b00 178| |
9d774aff
JD
179| ERRORS and NERRS can be used to store discovered explicit |
180| errors. |
c29240e7 181`------------------------------------------------------------------*/
08089d5d 182
4a120d45 183static void
9d774aff 184resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
08089d5d 185{
f041e30b
PE
186 symbol_number i;
187 reductions *reds = s->reductions;
9801d40c 188 /* Find the rule to reduce by to get precedence of reduction. */
f041e30b 189 rule *redrule = reds->rules[ruleno];
9801d40c 190 int redprec = redrule->prec->prec;
742e4900 191 bitset lookahead_tokens = reds->lookahead_tokens[ruleno];
08089d5d 192
08089d5d 193 for (i = 0; i < ntokens; i++)
742e4900
JD
194 if (bitset_test (lookahead_tokens, i)
195 && bitset_test (lookahead_set, i)
0e78e603 196 && symbols[i]->prec)
92b16366 197 {
709ae8c6
AD
198 /* Shift-reduce conflict occurs for token number i
199 and it has a precedence.
200 The precedence of shifting is that of token i. */
0e78e603 201 if (symbols[i]->prec < redprec)
92b16366 202 {
9801d40c 203 log_resolution (redrule, i, reduce_resolution);
f041e30b 204 flush_shift (s, i);
92b16366 205 }
0e78e603 206 else if (symbols[i]->prec > redprec)
92b16366 207 {
9801d40c 208 log_resolution (redrule, i, shift_resolution);
742e4900 209 flush_reduce (lookahead_tokens, i);
92b16366
AD
210 }
211 else
709ae8c6
AD
212 /* Matching precedence levels.
213 For left association, keep only the reduction.
214 For right association, keep only the shift.
215 For nonassociation, keep neither. */
216
5a670b1e 217 switch (symbols[i]->assoc)
709ae8c6 218 {
68cae94e
PE
219 default:
220 abort ();
221
709ae8c6 222 case right_assoc:
9801d40c 223 log_resolution (redrule, i, right_resolution);
742e4900 224 flush_reduce (lookahead_tokens, i);
709ae8c6
AD
225 break;
226
227 case left_assoc:
9801d40c 228 log_resolution (redrule, i, left_resolution);
f041e30b 229 flush_shift (s, i);
709ae8c6
AD
230 break;
231
232 case non_assoc:
9801d40c 233 log_resolution (redrule, i, nonassoc_resolution);
f041e30b 234 flush_shift (s, i);
742e4900 235 flush_reduce (lookahead_tokens, i);
709ae8c6 236 /* Record an explicit error for this token. */
9d774aff 237 errors[(*nerrs)++] = symbols[i];
709ae8c6
AD
238 break;
239 }
92b16366 240 }
08089d5d
DM
241}
242
243
8b752b00 244/*-------------------------------------------------------------------.
f041e30b 245| Solve the S/R conflicts of state S using the |
8b752b00 246| precedence/associativity, and flag it inconsistent if it still has |
f041e30b 247| conflicts. ERRORS can be used as storage to compute the list of |
742e4900 248| lookahead tokens on which S raises a syntax error (%nonassoc). |
8b752b00
AD
249`-------------------------------------------------------------------*/
250
4a120d45 251static void
f041e30b 252set_conflicts (state *s, symbol **errors)
08089d5d 253{
914feea9 254 int i;
f041e30b
PE
255 transitions *trans = s->transitions;
256 reductions *reds = s->reductions;
9d774aff 257 int nerrs = 0;
c29240e7 258
f041e30b 259 if (s->consistent)
c29240e7 260 return;
08089d5d 261
742e4900 262 bitset_zero (lookahead_set);
08089d5d 263
f041e30b 264 FOR_EACH_SHIFT (trans, i)
742e4900 265 bitset_set (lookahead_set, TRANSITION_SYMBOL (trans, i));
08089d5d 266
742e4900 267 /* Loop over all rules which require lookahead in this state. First
c29240e7 268 check for shift-reduce conflict, and try to resolve using
9801d40c 269 precedence. */
cd08e51e
AD
270 for (i = 0; i < reds->num; ++i)
271 if (reds->rules[i]->prec && reds->rules[i]->prec->prec
742e4900 272 && !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
9d774aff
JD
273 resolve_sr_conflict (s, i, errors, &nerrs);
274
275 if (nerrs)
276 {
277 /* Some tokens have been explicitly made errors. Allocate a
278 permanent errs structure for this state, to record them. */
279 state_errs_set (s, nerrs, errors);
280 }
281 if (obstack_object_size (&solved_conflicts_obstack))
282 {
283 obstack_1grow (&solved_conflicts_obstack, '\0');
284 s->solved_conflicts = obstack_finish (&solved_conflicts_obstack);
285 }
08089d5d 286
742e4900 287 /* Loop over all rules which require lookahead in this state. Check
c29240e7 288 for conflicts not resolved above. */
cd08e51e 289 for (i = 0; i < reds->num; ++i)
08089d5d 290 {
742e4900 291 if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
f041e30b 292 conflicts[s->number] = 1;
742e4900 293 bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
c29240e7
AD
294 }
295}
08089d5d 296
8b752b00
AD
297
298/*----------------------------------------------------------------.
299| Solve all the S/R conflicts using the precedence/associativity, |
300| and flag as inconsistent the states that still have conflicts. |
301`----------------------------------------------------------------*/
302
08089d5d 303void
b408954b 304conflicts_solve (void)
08089d5d 305{
f041e30b 306 state_number i;
742e4900 307 /* List of lookahead tokens on which we explicitly raise a syntax error. */
da2a7671 308 symbol **errors = xnmalloc (ntokens + 1, sizeof *errors);
08089d5d 309
da2a7671 310 conflicts = xcalloc (nstates, sizeof *conflicts);
8dd162d3 311 shift_set = bitset_create (ntokens, BITSET_FIXED);
742e4900 312 lookahead_set = bitset_create (ntokens, BITSET_FIXED);
b408954b 313 obstack_init (&solved_conflicts_obstack);
08089d5d 314
c29240e7 315 for (i = 0; i < nstates; i++)
8b752b00 316 {
f041e30b 317 set_conflicts (states[i], errors);
8b752b00
AD
318
319 /* For uniformity of the code, make sure all the states have a valid
320 `errs' member. */
321 if (!states[i]->errs)
322 states[i]->errs = errs_new (0, 0);
323 }
324
f041e30b 325 free (errors);
08089d5d
DM
326}
327
328
5967f0cf
JD
329void
330conflicts_update_state_numbers (state_number old_to_new[],
331 state_number nstates_old)
332{
14462c2b
JD
333 state_number i;
334 for (i = 0; i < nstates_old; ++i)
5967f0cf
JD
335 if (old_to_new[i] != nstates_old)
336 conflicts[old_to_new[i]] = conflicts[i];
337}
338
339
c29240e7
AD
340/*---------------------------------------------.
341| Count the number of shift/reduce conflicts. |
342`---------------------------------------------*/
343
0df87bb6 344static int
f041e30b 345count_sr_conflicts (state *s)
08089d5d 346{
f9abaa2c 347 int i;
0df87bb6 348 int src_count = 0;
f041e30b
PE
349 transitions *trans = s->transitions;
350 reductions *reds = s->reductions;
08089d5d 351
f041e30b 352 if (!trans)
0df87bb6 353 return 0;
08089d5d 354
742e4900 355 bitset_zero (lookahead_set);
8dd162d3 356 bitset_zero (shift_set);
08089d5d 357
f041e30b 358 FOR_EACH_SHIFT (trans, i)
8dd162d3 359 bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
08089d5d 360
cd08e51e 361 for (i = 0; i < reds->num; ++i)
742e4900 362 bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
08089d5d 363
742e4900 364 bitset_and (lookahead_set, lookahead_set, shift_set);
08089d5d 365
742e4900 366 src_count = bitset_count (lookahead_set);
0df87bb6
AD
367
368 return src_count;
08089d5d
DM
369}
370
371
676385e2
PH
372/*----------------------------------------------------------------.
373| Count the number of reduce/reduce conflicts. If ONE_PER_TOKEN, |
374| count one conflict for each token that has any reduce/reduce |
375| conflicts. Otherwise, count one conflict for each pair of |
376| conflicting reductions. |
377+`----------------------------------------------------------------*/
c29240e7 378
0df87bb6 379static int
d0829076 380count_rr_conflicts (state *s, bool one_per_token)
08089d5d 381{
c29240e7 382 int i;
f041e30b 383 reductions *reds = s->reductions;
0df87bb6 384 int rrc_count = 0;
08089d5d 385
08089d5d
DM
386 for (i = 0; i < ntokens; i++)
387 {
0df87bb6
AD
388 int count = 0;
389 int j;
cd08e51e 390 for (j = 0; j < reds->num; ++j)
742e4900 391 if (bitset_test (reds->lookahead_tokens[j], i))
52afa962 392 count++;
08089d5d 393
c29240e7 394 if (count >= 2)
676385e2 395 rrc_count += one_per_token ? 1 : count-1;
08089d5d 396 }
0df87bb6
AD
397
398 return rrc_count;
08089d5d
DM
399}
400
52489d44 401
be728048
PE
402/*--------------------------------------------------------.
403| Report the number of conflicts, using the Yacc format. |
404`--------------------------------------------------------*/
52489d44
AD
405
406static void
be728048 407conflict_report (FILE *out, int src_num, int rrc_num)
52489d44 408{
be728048
PE
409 if (src_num && rrc_num)
410 fprintf (out, _("conflicts: %d shift/reduce, %d reduce/reduce\n"),
411 src_num, rrc_num);
412 else if (src_num)
413 fprintf (out, _("conflicts: %d shift/reduce\n"), src_num);
414 else if (rrc_num)
415 fprintf (out, _("conflicts: %d reduce/reduce\n"), rrc_num);
52489d44
AD
416}
417
418
0df87bb6
AD
419/*-----------------------------------------------------------.
420| Output the detailed description of states with conflicts. |
421`-----------------------------------------------------------*/
c29240e7
AD
422
423void
0df87bb6 424conflicts_output (FILE *out)
c29240e7 425{
8307162d 426 bool printed_sth = false;
f041e30b 427 state_number i;
0df87bb6 428 for (i = 0; i < nstates; i++)
640748ee 429 {
f041e30b 430 state *s = states[i];
640748ee
AD
431 if (conflicts[i])
432 {
be728048
PE
433 fprintf (out, _("State %d "), i);
434 conflict_report (out, count_sr_conflicts (s),
435 count_rr_conflicts (s, true));
8307162d 436 printed_sth = true;
640748ee
AD
437 }
438 }
d2d1b42b
AD
439 if (printed_sth)
440 fputs ("\n\n", out);
0df87bb6 441}
c29240e7 442
676385e2
PH
443/*--------------------------------------------------------.
444| Total the number of S/R and R/R conflicts. Unlike the |
445| code in conflicts_output, however, count EACH pair of |
742e4900 446| reductions for the same state and lookahead as one |
676385e2
PH
447| conflict. |
448`--------------------------------------------------------*/
449
450int
451conflicts_total_count (void)
452{
f041e30b 453 state_number i;
676385e2
PH
454 int count;
455
456 /* Conflicts by state. */
457 count = 0;
458 for (i = 0; i < nstates; i++)
459 if (conflicts[i])
460 {
461 count += count_sr_conflicts (states[i]);
8307162d 462 count += count_rr_conflicts (states[i], false);
676385e2
PH
463 }
464 return count;
465}
e0e5bf84 466
c29240e7 467
0df87bb6
AD
468/*------------------------------------------.
469| Reporting the total number of conflicts. |
470`------------------------------------------*/
0619caf0 471
0df87bb6
AD
472void
473conflicts_print (void)
474{
a034c8b8
AD
475 /* Is the number of SR conflicts OK? Either EXPECTED_CONFLICTS is
476 not set, and then we want 0 SR, or else it is specified, in which
477 case we want equality. */
035aa4a0
PE
478 bool src_ok;
479 bool rrc_ok;
a034c8b8 480
0df87bb6
AD
481 int src_total = 0;
482 int rrc_total = 0;
035aa4a0
PE
483 int src_expected;
484 int rrc_expected;
0df87bb6
AD
485
486 /* Conflicts by state. */
d57650a5 487 {
f041e30b 488 state_number i;
d57650a5
AD
489
490 for (i = 0; i < nstates; i++)
491 if (conflicts[i])
492 {
493 src_total += count_sr_conflicts (states[i]);
8307162d 494 rrc_total += count_rr_conflicts (states[i], true);
d57650a5
AD
495 }
496 }
c29240e7 497
d6328241
PH
498 if (! glr_parser && rrc_total > 0 && expected_rr_conflicts != -1)
499 {
4f16766c 500 warn (_("%%expect-rr applies only to GLR parsers"));
d6328241
PH
501 expected_rr_conflicts = -1;
502 }
503
035aa4a0
PE
504 src_expected = expected_sr_conflicts == -1 ? 0 : expected_sr_conflicts;
505 rrc_expected = expected_rr_conflicts == -1 ? 0 : expected_rr_conflicts;
506 src_ok = src_total == src_expected;
507 rrc_ok = rrc_total == rrc_expected;
a034c8b8 508
d6328241 509 /* If there are as many RR conflicts and SR conflicts as
a034c8b8 510 expected, then there is nothing to report. */
035aa4a0 511 if (rrc_ok & src_ok)
a034c8b8
AD
512 return;
513
0619caf0 514 /* Report the total number of conflicts on STDERR. */
035aa4a0
PE
515 if (src_total | rrc_total)
516 {
517 if (! yacc_flag)
518 fprintf (stderr, "%s: ", current_file);
519 conflict_report (stderr, src_total, rrc_total);
520 }
7da99ede 521
d6328241 522 if (expected_sr_conflicts != -1 || expected_rr_conflicts != -1)
76be9271
PE
523 {
524 if (! src_ok)
035aa4a0
PE
525 complain (ngettext ("expected %d shift/reduce conflict",
526 "expected %d shift/reduce conflicts",
527 src_expected),
528 src_expected);
d6328241 529 if (! rrc_ok)
035aa4a0
PE
530 complain (ngettext ("expected %d reduce/reduce conflict",
531 "expected %d reduce/reduce conflicts",
532 rrc_expected),
533 rrc_expected);
76be9271 534 }
c29240e7
AD
535}
536
537
08089d5d 538void
b408954b 539conflicts_free (void)
08089d5d 540{
afbb696d 541 free (conflicts);
8dd162d3 542 bitset_free (shift_set);
742e4900 543 bitset_free (lookahead_set);
b408954b 544 obstack_free (&solved_conflicts_obstack, NULL);
08089d5d 545}