]> git.saurik.com Git - bison.git/blame - src/conflicts.c
* lib/.cvsignore: Add charset.alias.
[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 |
141| favor of the reduction. |
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
PE
158/*--------------------------------------------------------------------.
159| Turn off the reduce recorded for the specified token for the |
742e4900 160| specified lookahead. Used when we resolve a shift-reduce conflict |
8dd162d3
PE
161| in favor of the shift. |
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| |
f041e30b 179| ERRORS can be used to store discovered explicit errors. |
c29240e7 180`------------------------------------------------------------------*/
08089d5d 181
4a120d45 182static void
f041e30b 183resolve_sr_conflict (state *s, int ruleno, symbol **errors)
08089d5d 184{
f041e30b
PE
185 symbol_number i;
186 reductions *reds = s->reductions;
9801d40c 187 /* Find the rule to reduce by to get precedence of reduction. */
f041e30b 188 rule *redrule = reds->rules[ruleno];
9801d40c 189 int redprec = redrule->prec->prec;
742e4900 190 bitset lookahead_tokens = reds->lookahead_tokens[ruleno];
8b752b00 191 int nerrs = 0;
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. */
f041e30b 237 errors[nerrs++] = symbols[i];
709ae8c6
AD
238 break;
239 }
92b16366
AD
240 }
241
0de45ae5
PE
242 if (nerrs)
243 {
244 /* Some tokens have been explicitly made errors. Allocate a
245 permanent errs structure for this state, to record them. */
246 state_errs_set (s, nerrs, errors);
247 }
b408954b
AD
248
249 if (obstack_object_size (&solved_conflicts_obstack))
250 {
251 obstack_1grow (&solved_conflicts_obstack, '\0');
f041e30b 252 s->solved_conflicts = obstack_finish (&solved_conflicts_obstack);
b408954b 253 }
08089d5d
DM
254}
255
256
8b752b00 257/*-------------------------------------------------------------------.
f041e30b 258| Solve the S/R conflicts of state S using the |
8b752b00 259| precedence/associativity, and flag it inconsistent if it still has |
f041e30b 260| conflicts. ERRORS can be used as storage to compute the list of |
742e4900 261| lookahead tokens on which S raises a syntax error (%nonassoc). |
8b752b00
AD
262`-------------------------------------------------------------------*/
263
4a120d45 264static void
f041e30b 265set_conflicts (state *s, symbol **errors)
08089d5d 266{
914feea9 267 int i;
f041e30b
PE
268 transitions *trans = s->transitions;
269 reductions *reds = s->reductions;
c29240e7 270
f041e30b 271 if (s->consistent)
c29240e7 272 return;
08089d5d 273
742e4900 274 bitset_zero (lookahead_set);
08089d5d 275
f041e30b 276 FOR_EACH_SHIFT (trans, i)
742e4900 277 bitset_set (lookahead_set, TRANSITION_SYMBOL (trans, i));
08089d5d 278
742e4900 279 /* Loop over all rules which require lookahead in this state. First
c29240e7 280 check for shift-reduce conflict, and try to resolve using
9801d40c 281 precedence. */
cd08e51e
AD
282 for (i = 0; i < reds->num; ++i)
283 if (reds->rules[i]->prec && reds->rules[i]->prec->prec
742e4900 284 && !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
0de45ae5 285 resolve_sr_conflict (s, i, errors);
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;
08089d5d 293
742e4900 294 bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
c29240e7
AD
295 }
296}
08089d5d 297
8b752b00
AD
298
299/*----------------------------------------------------------------.
300| Solve all the S/R conflicts using the precedence/associativity, |
301| and flag as inconsistent the states that still have conflicts. |
302`----------------------------------------------------------------*/
303
08089d5d 304void
b408954b 305conflicts_solve (void)
08089d5d 306{
f041e30b 307 state_number i;
742e4900 308 /* List of lookahead tokens on which we explicitly raise a syntax error. */
da2a7671 309 symbol **errors = xnmalloc (ntokens + 1, sizeof *errors);
08089d5d 310
da2a7671 311 conflicts = xcalloc (nstates, sizeof *conflicts);
8dd162d3 312 shift_set = bitset_create (ntokens, BITSET_FIXED);
742e4900 313 lookahead_set = bitset_create (ntokens, BITSET_FIXED);
b408954b 314 obstack_init (&solved_conflicts_obstack);
08089d5d 315
c29240e7 316 for (i = 0; i < nstates; i++)
8b752b00 317 {
f041e30b 318 set_conflicts (states[i], errors);
8b752b00
AD
319
320 /* For uniformity of the code, make sure all the states have a valid
321 `errs' member. */
322 if (!states[i]->errs)
323 states[i]->errs = errs_new (0, 0);
324 }
325
f041e30b 326 free (errors);
08089d5d
DM
327}
328
329
5967f0cf
JD
330void
331conflicts_update_state_numbers (state_number old_to_new[],
332 state_number nstates_old)
333{
14462c2b
JD
334 state_number i;
335 for (i = 0; i < nstates_old; ++i)
5967f0cf
JD
336 if (old_to_new[i] != nstates_old)
337 conflicts[old_to_new[i]] = conflicts[i];
338}
339
340
c29240e7
AD
341/*---------------------------------------------.
342| Count the number of shift/reduce conflicts. |
343`---------------------------------------------*/
344
0df87bb6 345static int
f041e30b 346count_sr_conflicts (state *s)
08089d5d 347{
f9abaa2c 348 int i;
0df87bb6 349 int src_count = 0;
f041e30b
PE
350 transitions *trans = s->transitions;
351 reductions *reds = s->reductions;
08089d5d 352
f041e30b 353 if (!trans)
0df87bb6 354 return 0;
08089d5d 355
742e4900 356 bitset_zero (lookahead_set);
8dd162d3 357 bitset_zero (shift_set);
08089d5d 358
f041e30b 359 FOR_EACH_SHIFT (trans, i)
8dd162d3 360 bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
08089d5d 361
cd08e51e 362 for (i = 0; i < reds->num; ++i)
742e4900 363 bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
08089d5d 364
742e4900 365 bitset_and (lookahead_set, lookahead_set, shift_set);
08089d5d 366
742e4900 367 src_count = bitset_count (lookahead_set);
0df87bb6
AD
368
369 return src_count;
08089d5d
DM
370}
371
372
676385e2
PH
373/*----------------------------------------------------------------.
374| Count the number of reduce/reduce conflicts. If ONE_PER_TOKEN, |
375| count one conflict for each token that has any reduce/reduce |
376| conflicts. Otherwise, count one conflict for each pair of |
377| conflicting reductions. |
378+`----------------------------------------------------------------*/
c29240e7 379
0df87bb6 380static int
d0829076 381count_rr_conflicts (state *s, bool one_per_token)
08089d5d 382{
c29240e7 383 int i;
f041e30b 384 reductions *reds = s->reductions;
0df87bb6 385 int rrc_count = 0;
08089d5d 386
08089d5d
DM
387 for (i = 0; i < ntokens; i++)
388 {
0df87bb6
AD
389 int count = 0;
390 int j;
cd08e51e 391 for (j = 0; j < reds->num; ++j)
742e4900 392 if (bitset_test (reds->lookahead_tokens[j], i))
52afa962 393 count++;
08089d5d 394
c29240e7 395 if (count >= 2)
676385e2 396 rrc_count += one_per_token ? 1 : count-1;
08089d5d 397 }
0df87bb6
AD
398
399 return rrc_count;
08089d5d
DM
400}
401
52489d44 402
be728048
PE
403/*--------------------------------------------------------.
404| Report the number of conflicts, using the Yacc format. |
405`--------------------------------------------------------*/
52489d44
AD
406
407static void
be728048 408conflict_report (FILE *out, int src_num, int rrc_num)
52489d44 409{
be728048
PE
410 if (src_num && rrc_num)
411 fprintf (out, _("conflicts: %d shift/reduce, %d reduce/reduce\n"),
412 src_num, rrc_num);
413 else if (src_num)
414 fprintf (out, _("conflicts: %d shift/reduce\n"), src_num);
415 else if (rrc_num)
416 fprintf (out, _("conflicts: %d reduce/reduce\n"), rrc_num);
52489d44
AD
417}
418
419
0df87bb6
AD
420/*-----------------------------------------------------------.
421| Output the detailed description of states with conflicts. |
422`-----------------------------------------------------------*/
c29240e7
AD
423
424void
0df87bb6 425conflicts_output (FILE *out)
c29240e7 426{
8307162d 427 bool printed_sth = false;
f041e30b 428 state_number i;
0df87bb6 429 for (i = 0; i < nstates; i++)
640748ee 430 {
f041e30b 431 state *s = states[i];
640748ee
AD
432 if (conflicts[i])
433 {
be728048
PE
434 fprintf (out, _("State %d "), i);
435 conflict_report (out, count_sr_conflicts (s),
436 count_rr_conflicts (s, true));
8307162d 437 printed_sth = true;
640748ee
AD
438 }
439 }
d2d1b42b
AD
440 if (printed_sth)
441 fputs ("\n\n", out);
0df87bb6 442}
c29240e7 443
676385e2
PH
444/*--------------------------------------------------------.
445| Total the number of S/R and R/R conflicts. Unlike the |
446| code in conflicts_output, however, count EACH pair of |
742e4900 447| reductions for the same state and lookahead as one |
676385e2
PH
448| conflict. |
449`--------------------------------------------------------*/
450
451int
452conflicts_total_count (void)
453{
f041e30b 454 state_number i;
676385e2
PH
455 int count;
456
457 /* Conflicts by state. */
458 count = 0;
459 for (i = 0; i < nstates; i++)
460 if (conflicts[i])
461 {
462 count += count_sr_conflicts (states[i]);
8307162d 463 count += count_rr_conflicts (states[i], false);
676385e2
PH
464 }
465 return count;
466}
e0e5bf84 467
c29240e7 468
0df87bb6
AD
469/*------------------------------------------.
470| Reporting the total number of conflicts. |
471`------------------------------------------*/
0619caf0 472
0df87bb6
AD
473void
474conflicts_print (void)
475{
a034c8b8
AD
476 /* Is the number of SR conflicts OK? Either EXPECTED_CONFLICTS is
477 not set, and then we want 0 SR, or else it is specified, in which
478 case we want equality. */
035aa4a0
PE
479 bool src_ok;
480 bool rrc_ok;
a034c8b8 481
0df87bb6
AD
482 int src_total = 0;
483 int rrc_total = 0;
035aa4a0
PE
484 int src_expected;
485 int rrc_expected;
0df87bb6
AD
486
487 /* Conflicts by state. */
d57650a5 488 {
f041e30b 489 state_number i;
d57650a5
AD
490
491 for (i = 0; i < nstates; i++)
492 if (conflicts[i])
493 {
494 src_total += count_sr_conflicts (states[i]);
8307162d 495 rrc_total += count_rr_conflicts (states[i], true);
d57650a5
AD
496 }
497 }
c29240e7 498
d6328241
PH
499 if (! glr_parser && rrc_total > 0 && expected_rr_conflicts != -1)
500 {
4f16766c 501 warn (_("%%expect-rr applies only to GLR parsers"));
d6328241
PH
502 expected_rr_conflicts = -1;
503 }
504
035aa4a0
PE
505 src_expected = expected_sr_conflicts == -1 ? 0 : expected_sr_conflicts;
506 rrc_expected = expected_rr_conflicts == -1 ? 0 : expected_rr_conflicts;
507 src_ok = src_total == src_expected;
508 rrc_ok = rrc_total == rrc_expected;
a034c8b8 509
d6328241 510 /* If there are as many RR conflicts and SR conflicts as
a034c8b8 511 expected, then there is nothing to report. */
035aa4a0 512 if (rrc_ok & src_ok)
a034c8b8
AD
513 return;
514
0619caf0 515 /* Report the total number of conflicts on STDERR. */
035aa4a0
PE
516 if (src_total | rrc_total)
517 {
518 if (! yacc_flag)
519 fprintf (stderr, "%s: ", current_file);
520 conflict_report (stderr, src_total, rrc_total);
521 }
7da99ede 522
d6328241 523 if (expected_sr_conflicts != -1 || expected_rr_conflicts != -1)
76be9271
PE
524 {
525 if (! src_ok)
035aa4a0
PE
526 complain (ngettext ("expected %d shift/reduce conflict",
527 "expected %d shift/reduce conflicts",
528 src_expected),
529 src_expected);
d6328241 530 if (! rrc_ok)
035aa4a0
PE
531 complain (ngettext ("expected %d reduce/reduce conflict",
532 "expected %d reduce/reduce conflicts",
533 rrc_expected),
534 rrc_expected);
76be9271 535 }
c29240e7
AD
536}
537
538
08089d5d 539void
b408954b 540conflicts_free (void)
08089d5d 541{
afbb696d 542 free (conflicts);
8dd162d3 543 bitset_free (shift_set);
742e4900 544 bitset_free (lookahead_set);
b408954b 545 obstack_free (&solved_conflicts_obstack, NULL);
08089d5d 546}