]> git.saurik.com Git - bison.git/blame - src/conflicts.c
* src/conflicts.c (log_resolution): Fix indenting bugs I introduced.
[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
f16b0819
PE
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.
08089d5d 12
f16b0819
PE
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.
08089d5d 17
ceed8467 18 You should have received a copy of the GNU General Public License
f16b0819 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
08089d5d 20
2cec9080 21#include <config.h>
08089d5d 22#include "system.h"
f041e30b
PE
23
24#include <bitset.h>
25
26#include "LR0.h"
7da99ede 27#include "complain.h"
f041e30b 28#include "conflicts.h"
08089d5d 29#include "files.h"
f041e30b 30#include "getargs.h"
08089d5d 31#include "gram.h"
720d742f 32#include "lalr.h"
41d7a5f2 33#include "print-xml.h"
b2ca4022 34#include "reader.h"
f041e30b
PE
35#include "state.h"
36#include "symtab.h"
d2729d44 37
7da99ede 38/* -1 stands for not specified. */
d6328241
PH
39int expected_sr_conflicts = -1;
40int expected_rr_conflicts = -1;
da2a7671 41static char *conflicts;
d6b771c3 42static struct obstack solved_conflicts_obstack;
41d7a5f2 43static struct obstack solved_conflicts_xml_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 76 obstack_fgrow2 (&solved_conflicts_obstack,
41d7a5f2
PE
77 _(" Conflict between rule %d and token %s"
78 " resolved as shift"),
f041e30b 79 r->number,
b408954b
AD
80 symbols[token]->tag);
81 break;
41d7a5f2 82
b408954b 83 case reduce_resolution:
4b3d3a8e 84 case left_resolution:
b408954b 85 obstack_fgrow2 (&solved_conflicts_obstack,
41d7a5f2
PE
86 _(" Conflict between rule %d and token %s"
87 " resolved as reduce"),
f041e30b 88 r->number,
b408954b
AD
89 symbols[token]->tag);
90 break;
41d7a5f2 91
b408954b
AD
92 case nonassoc_resolution:
93 obstack_fgrow2 (&solved_conflicts_obstack,
41d7a5f2
PE
94 _(" Conflict between rule %d and token %s"
95 " resolved as an error"),
f041e30b 96 r->number,
b408954b
AD
97 symbols[token]->tag);
98 break;
99 }
100
101 /* The reason. */
102 switch (resolution)
103 {
104 case shift_resolution:
105 obstack_fgrow2 (&solved_conflicts_obstack,
106 " (%s < %s)",
f041e30b 107 r->prec->tag,
b408954b
AD
108 symbols[token]->tag);
109 break;
110
111 case reduce_resolution:
112 obstack_fgrow2 (&solved_conflicts_obstack,
113 " (%s < %s)",
114 symbols[token]->tag,
f041e30b 115 r->prec->tag);
b408954b
AD
116 break;
117
118 case left_resolution:
4a713ec2 119 obstack_fgrow1 (&solved_conflicts_obstack,
b408954b
AD
120 " (%%left %s)",
121 symbols[token]->tag);
122 break;
123
124 case right_resolution:
125 obstack_fgrow1 (&solved_conflicts_obstack,
126 " (%%right %s)",
127 symbols[token]->tag);
128 break;
41d7a5f2 129
b408954b
AD
130 case nonassoc_resolution:
131 obstack_fgrow1 (&solved_conflicts_obstack,
132 " (%%nonassoc %s)",
133 symbols[token]->tag);
134 break;
135 }
41d7a5f2 136
b408954b 137 obstack_sgrow (&solved_conflicts_obstack, ".\n");
41d7a5f2
PE
138
139 /* XML report */
140 if (xml_flag)
141 {
142 /* The description of the resolution. */
143 switch (resolution)
144 {
145 case shift_resolution:
146 case right_resolution:
147 obstack_fgrow2 (&solved_conflicts_xml_obstack,
a4f75309 148 " <resolution rule=\"%d\" symbol=\"%s\""
41d7a5f2
PE
149 " type=\"shift\">",
150 r->number,
151 xml_escape (symbols[token]->tag));
152 break;
153
154 case reduce_resolution:
155 case left_resolution:
156 obstack_fgrow2 (&solved_conflicts_xml_obstack,
a4f75309 157 " <resolution rule=\"%d\" symbol=\"%s\""
41d7a5f2
PE
158 " type=\"reduce\">",
159 r->number,
160 xml_escape (symbols[token]->tag));
161 break;
162
163 case nonassoc_resolution:
164 obstack_fgrow2 (&solved_conflicts_xml_obstack,
a4f75309 165 " <resolution rule=\"%d\" symbol=\"%s\""
41d7a5f2
PE
166 " type=\"error\">",
167 r->number,
168 xml_escape (symbols[token]->tag));
169 break;
170 }
171
172 /* The reason. */
173 switch (resolution)
174 {
175 case shift_resolution:
176 obstack_fgrow2 (&solved_conflicts_xml_obstack,
177 "%s &lt; %s",
178 xml_escape_n (0, r->prec->tag),
179 xml_escape_n (1, symbols[token]->tag));
180 break;
181
182 case reduce_resolution:
183 obstack_fgrow2 (&solved_conflicts_xml_obstack,
184 "%s &lt; %s",
185 xml_escape_n (0, symbols[token]->tag),
186 xml_escape_n (1, r->prec->tag));
187 break;
188
189 case left_resolution:
190 obstack_fgrow1 (&solved_conflicts_xml_obstack,
191 "%%left %s",
192 xml_escape (symbols[token]->tag));
193 break;
194
195 case right_resolution:
196 obstack_fgrow1 (&solved_conflicts_xml_obstack,
197 "%%right %s",
198 xml_escape (symbols[token]->tag));
199 break;
200
201 case nonassoc_resolution:
202 obstack_fgrow1 (&solved_conflicts_xml_obstack,
203 "%%nonassoc %s",
204 xml_escape (symbols[token]->tag));
205 break;
206 }
207
208 obstack_sgrow (&solved_conflicts_xml_obstack, "</resolution>\n");
209 }
b408954b 210 }
08089d5d
DM
211}
212
213
c29240e7
AD
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 |
9d774aff 217| favor of the reduction or as an error (%nonassoc). |
c29240e7
AD
218`------------------------------------------------------------------*/
219
4a120d45 220static void
f041e30b 221flush_shift (state *s, int token)
08089d5d 222{
f041e30b 223 transitions *trans = s->transitions;
9f136c07 224 int i;
c29240e7 225
742e4900 226 bitset_reset (lookahead_set, token);
f041e30b
PE
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);
08089d5d
DM
231}
232
233
8dd162d3 234/*--------------------------------------------------------------------.
9d774aff
JD
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). |
8dd162d3 238`--------------------------------------------------------------------*/
709ae8c6
AD
239
240static void
742e4900 241flush_reduce (bitset lookahead_tokens, int token)
709ae8c6 242{
742e4900 243 bitset_reset (lookahead_tokens, token);
709ae8c6
AD
244}
245
246
c29240e7
AD
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. |
9801d40c 252| |
742e4900 253| RULENO is the number of the lookahead bitset to consider. |
8b752b00 254| |
9d774aff
JD
255| ERRORS and NERRS can be used to store discovered explicit |
256| errors. |
c29240e7 257`------------------------------------------------------------------*/
08089d5d 258
4a120d45 259static void
9d774aff 260resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
08089d5d 261{
f041e30b
PE
262 symbol_number i;
263 reductions *reds = s->reductions;
9801d40c 264 /* Find the rule to reduce by to get precedence of reduction. */
f041e30b 265 rule *redrule = reds->rules[ruleno];
9801d40c 266 int redprec = redrule->prec->prec;
742e4900 267 bitset lookahead_tokens = reds->lookahead_tokens[ruleno];
08089d5d 268
08089d5d 269 for (i = 0; i < ntokens; i++)
742e4900
JD
270 if (bitset_test (lookahead_tokens, i)
271 && bitset_test (lookahead_set, i)
0e78e603 272 && symbols[i]->prec)
92b16366 273 {
709ae8c6
AD
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. */
0e78e603 277 if (symbols[i]->prec < redprec)
92b16366 278 {
9801d40c 279 log_resolution (redrule, i, reduce_resolution);
f041e30b 280 flush_shift (s, i);
92b16366 281 }
0e78e603 282 else if (symbols[i]->prec > redprec)
92b16366 283 {
9801d40c 284 log_resolution (redrule, i, shift_resolution);
742e4900 285 flush_reduce (lookahead_tokens, i);
92b16366
AD
286 }
287 else
709ae8c6
AD
288 /* Matching precedence levels.
289 For left association, keep only the reduction.
290 For right association, keep only the shift.
291 For nonassociation, keep neither. */
292
5a670b1e 293 switch (symbols[i]->assoc)
709ae8c6 294 {
68cae94e
PE
295 default:
296 abort ();
297
709ae8c6 298 case right_assoc:
9801d40c 299 log_resolution (redrule, i, right_resolution);
742e4900 300 flush_reduce (lookahead_tokens, i);
709ae8c6
AD
301 break;
302
303 case left_assoc:
9801d40c 304 log_resolution (redrule, i, left_resolution);
f041e30b 305 flush_shift (s, i);
709ae8c6
AD
306 break;
307
308 case non_assoc:
9801d40c 309 log_resolution (redrule, i, nonassoc_resolution);
f041e30b 310 flush_shift (s, i);
742e4900 311 flush_reduce (lookahead_tokens, i);
709ae8c6 312 /* Record an explicit error for this token. */
9d774aff 313 errors[(*nerrs)++] = symbols[i];
709ae8c6
AD
314 break;
315 }
92b16366 316 }
08089d5d
DM
317}
318
319
8b752b00 320/*-------------------------------------------------------------------.
f041e30b 321| Solve the S/R conflicts of state S using the |
8b752b00 322| precedence/associativity, and flag it inconsistent if it still has |
f041e30b 323| conflicts. ERRORS can be used as storage to compute the list of |
742e4900 324| lookahead tokens on which S raises a syntax error (%nonassoc). |
8b752b00
AD
325`-------------------------------------------------------------------*/
326
4a120d45 327static void
f041e30b 328set_conflicts (state *s, symbol **errors)
08089d5d 329{
914feea9 330 int i;
f041e30b
PE
331 transitions *trans = s->transitions;
332 reductions *reds = s->reductions;
9d774aff 333 int nerrs = 0;
c29240e7 334
f041e30b 335 if (s->consistent)
c29240e7 336 return;
08089d5d 337
742e4900 338 bitset_zero (lookahead_set);
08089d5d 339
f041e30b 340 FOR_EACH_SHIFT (trans, i)
742e4900 341 bitset_set (lookahead_set, TRANSITION_SYMBOL (trans, i));
08089d5d 342
742e4900 343 /* Loop over all rules which require lookahead in this state. First
c29240e7 344 check for shift-reduce conflict, and try to resolve using
9801d40c 345 precedence. */
cd08e51e
AD
346 for (i = 0; i < reds->num; ++i)
347 if (reds->rules[i]->prec && reds->rules[i]->prec->prec
742e4900 348 && !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
9d774aff
JD
349 resolve_sr_conflict (s, i, errors, &nerrs);
350
351 if (nerrs)
352 {
353 /* Some tokens have been explicitly made errors. Allocate a
354 permanent errs structure for this state, to record them. */
355 state_errs_set (s, nerrs, errors);
356 }
357 if (obstack_object_size (&solved_conflicts_obstack))
358 {
359 obstack_1grow (&solved_conflicts_obstack, '\0');
360 s->solved_conflicts = obstack_finish (&solved_conflicts_obstack);
361 }
41d7a5f2
PE
362 if (obstack_object_size (&solved_conflicts_xml_obstack))
363 {
364 obstack_1grow (&solved_conflicts_xml_obstack, '\0');
365 s->solved_conflicts_xml = obstack_finish (&solved_conflicts_xml_obstack);
366 }
08089d5d 367
742e4900 368 /* Loop over all rules which require lookahead in this state. Check
c29240e7 369 for conflicts not resolved above. */
cd08e51e 370 for (i = 0; i < reds->num; ++i)
08089d5d 371 {
742e4900 372 if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
f041e30b 373 conflicts[s->number] = 1;
742e4900 374 bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
c29240e7
AD
375 }
376}
08089d5d 377
8b752b00
AD
378
379/*----------------------------------------------------------------.
380| Solve all the S/R conflicts using the precedence/associativity, |
381| and flag as inconsistent the states that still have conflicts. |
382`----------------------------------------------------------------*/
383
08089d5d 384void
b408954b 385conflicts_solve (void)
08089d5d 386{
f041e30b 387 state_number i;
742e4900 388 /* List of lookahead tokens on which we explicitly raise a syntax error. */
da2a7671 389 symbol **errors = xnmalloc (ntokens + 1, sizeof *errors);
08089d5d 390
da2a7671 391 conflicts = xcalloc (nstates, sizeof *conflicts);
8dd162d3 392 shift_set = bitset_create (ntokens, BITSET_FIXED);
742e4900 393 lookahead_set = bitset_create (ntokens, BITSET_FIXED);
b408954b 394 obstack_init (&solved_conflicts_obstack);
41d7a5f2 395 obstack_init (&solved_conflicts_xml_obstack);
08089d5d 396
c29240e7 397 for (i = 0; i < nstates; i++)
8b752b00 398 {
f041e30b 399 set_conflicts (states[i], errors);
8b752b00
AD
400
401 /* For uniformity of the code, make sure all the states have a valid
402 `errs' member. */
403 if (!states[i]->errs)
404 states[i]->errs = errs_new (0, 0);
405 }
406
f041e30b 407 free (errors);
08089d5d
DM
408}
409
410
5967f0cf
JD
411void
412conflicts_update_state_numbers (state_number old_to_new[],
413 state_number nstates_old)
414{
14462c2b
JD
415 state_number i;
416 for (i = 0; i < nstates_old; ++i)
5967f0cf
JD
417 if (old_to_new[i] != nstates_old)
418 conflicts[old_to_new[i]] = conflicts[i];
419}
420
421
c29240e7
AD
422/*---------------------------------------------.
423| Count the number of shift/reduce conflicts. |
424`---------------------------------------------*/
425
0df87bb6 426static int
f041e30b 427count_sr_conflicts (state *s)
08089d5d 428{
f9abaa2c 429 int i;
0df87bb6 430 int src_count = 0;
f041e30b
PE
431 transitions *trans = s->transitions;
432 reductions *reds = s->reductions;
08089d5d 433
f041e30b 434 if (!trans)
0df87bb6 435 return 0;
08089d5d 436
742e4900 437 bitset_zero (lookahead_set);
8dd162d3 438 bitset_zero (shift_set);
08089d5d 439
f041e30b 440 FOR_EACH_SHIFT (trans, i)
8dd162d3 441 bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
08089d5d 442
cd08e51e 443 for (i = 0; i < reds->num; ++i)
742e4900 444 bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
08089d5d 445
742e4900 446 bitset_and (lookahead_set, lookahead_set, shift_set);
08089d5d 447
742e4900 448 src_count = bitset_count (lookahead_set);
0df87bb6
AD
449
450 return src_count;
08089d5d
DM
451}
452
453
676385e2
PH
454/*----------------------------------------------------------------.
455| Count the number of reduce/reduce conflicts. If ONE_PER_TOKEN, |
456| count one conflict for each token that has any reduce/reduce |
457| conflicts. Otherwise, count one conflict for each pair of |
458| conflicting reductions. |
459+`----------------------------------------------------------------*/
c29240e7 460
0df87bb6 461static int
d0829076 462count_rr_conflicts (state *s, bool one_per_token)
08089d5d 463{
c29240e7 464 int i;
f041e30b 465 reductions *reds = s->reductions;
0df87bb6 466 int rrc_count = 0;
08089d5d 467
08089d5d
DM
468 for (i = 0; i < ntokens; i++)
469 {
0df87bb6
AD
470 int count = 0;
471 int j;
cd08e51e 472 for (j = 0; j < reds->num; ++j)
742e4900 473 if (bitset_test (reds->lookahead_tokens[j], i))
52afa962 474 count++;
08089d5d 475
c29240e7 476 if (count >= 2)
676385e2 477 rrc_count += one_per_token ? 1 : count-1;
08089d5d 478 }
0df87bb6
AD
479
480 return rrc_count;
08089d5d
DM
481}
482
52489d44 483
be728048
PE
484/*--------------------------------------------------------.
485| Report the number of conflicts, using the Yacc format. |
486`--------------------------------------------------------*/
52489d44
AD
487
488static void
be728048 489conflict_report (FILE *out, int src_num, int rrc_num)
52489d44 490{
be728048
PE
491 if (src_num && rrc_num)
492 fprintf (out, _("conflicts: %d shift/reduce, %d reduce/reduce\n"),
493 src_num, rrc_num);
494 else if (src_num)
495 fprintf (out, _("conflicts: %d shift/reduce\n"), src_num);
496 else if (rrc_num)
497 fprintf (out, _("conflicts: %d reduce/reduce\n"), rrc_num);
52489d44
AD
498}
499
500
0df87bb6
AD
501/*-----------------------------------------------------------.
502| Output the detailed description of states with conflicts. |
503`-----------------------------------------------------------*/
c29240e7
AD
504
505void
0df87bb6 506conflicts_output (FILE *out)
c29240e7 507{
8307162d 508 bool printed_sth = false;
f041e30b 509 state_number i;
0df87bb6 510 for (i = 0; i < nstates; i++)
640748ee 511 {
f041e30b 512 state *s = states[i];
640748ee
AD
513 if (conflicts[i])
514 {
be728048
PE
515 fprintf (out, _("State %d "), i);
516 conflict_report (out, count_sr_conflicts (s),
517 count_rr_conflicts (s, true));
8307162d 518 printed_sth = true;
640748ee
AD
519 }
520 }
d2d1b42b
AD
521 if (printed_sth)
522 fputs ("\n\n", out);
0df87bb6 523}
c29240e7 524
41d7a5f2
PE
525void
526conflicts_output_xml (FILE *out, int level)
527{
528 bool printed_sth = false;
529 state_number i;
530 int src_num;
531 int rrc_num;
532
533 for (i = 0; i < nstates; i++)
534 {
535 state *s = states[i];
536 if (conflicts[i])
537 {
538 if (!printed_sth) {
539 fputc ('\n', out);
540 xml_puts (out, level, "<conflicts>");
541 }
542
543 src_num = count_sr_conflicts (s);
544 rrc_num = count_rr_conflicts (s, true);
545
546 if (src_num)
547 xml_printf (out, level + 1,
548 "<conflict state=\"%d\" num=\"%d\""
549 " type=\"shift/reduce\"/>",
550 i, src_num);
551 if (rrc_num)
552 xml_printf (out, level + 1,
553 "<conflict state=\"%d\" num=\"%d\""
554 " type=\"reduce/reduce\"/>",
555 i, rrc_num);
556
557 printed_sth = true;
558 }
559 }
560 if (printed_sth)
561 xml_puts (out, level, "</conflicts>");
562 else
563 xml_puts (out, level, "<conflicts/>");
564}
565
676385e2
PH
566/*--------------------------------------------------------.
567| Total the number of S/R and R/R conflicts. Unlike the |
568| code in conflicts_output, however, count EACH pair of |
742e4900 569| reductions for the same state and lookahead as one |
676385e2
PH
570| conflict. |
571`--------------------------------------------------------*/
572
573int
574conflicts_total_count (void)
575{
f041e30b 576 state_number i;
676385e2
PH
577 int count;
578
579 /* Conflicts by state. */
580 count = 0;
581 for (i = 0; i < nstates; i++)
582 if (conflicts[i])
583 {
584 count += count_sr_conflicts (states[i]);
8307162d 585 count += count_rr_conflicts (states[i], false);
676385e2
PH
586 }
587 return count;
588}
e0e5bf84 589
c29240e7 590
0df87bb6
AD
591/*------------------------------------------.
592| Reporting the total number of conflicts. |
593`------------------------------------------*/
0619caf0 594
0df87bb6
AD
595void
596conflicts_print (void)
597{
a034c8b8
AD
598 /* Is the number of SR conflicts OK? Either EXPECTED_CONFLICTS is
599 not set, and then we want 0 SR, or else it is specified, in which
600 case we want equality. */
035aa4a0
PE
601 bool src_ok;
602 bool rrc_ok;
a034c8b8 603
0df87bb6
AD
604 int src_total = 0;
605 int rrc_total = 0;
035aa4a0
PE
606 int src_expected;
607 int rrc_expected;
0df87bb6
AD
608
609 /* Conflicts by state. */
d57650a5 610 {
f041e30b 611 state_number i;
d57650a5
AD
612
613 for (i = 0; i < nstates; i++)
614 if (conflicts[i])
615 {
616 src_total += count_sr_conflicts (states[i]);
8307162d 617 rrc_total += count_rr_conflicts (states[i], true);
d57650a5
AD
618 }
619 }
c29240e7 620
d6328241
PH
621 if (! glr_parser && rrc_total > 0 && expected_rr_conflicts != -1)
622 {
4f16766c 623 warn (_("%%expect-rr applies only to GLR parsers"));
d6328241
PH
624 expected_rr_conflicts = -1;
625 }
626
035aa4a0
PE
627 src_expected = expected_sr_conflicts == -1 ? 0 : expected_sr_conflicts;
628 rrc_expected = expected_rr_conflicts == -1 ? 0 : expected_rr_conflicts;
629 src_ok = src_total == src_expected;
630 rrc_ok = rrc_total == rrc_expected;
a034c8b8 631
d6328241 632 /* If there are as many RR conflicts and SR conflicts as
a034c8b8 633 expected, then there is nothing to report. */
035aa4a0 634 if (rrc_ok & src_ok)
a034c8b8
AD
635 return;
636
0619caf0 637 /* Report the total number of conflicts on STDERR. */
035aa4a0
PE
638 if (src_total | rrc_total)
639 {
640 if (! yacc_flag)
641 fprintf (stderr, "%s: ", current_file);
642 conflict_report (stderr, src_total, rrc_total);
643 }
7da99ede 644
d6328241 645 if (expected_sr_conflicts != -1 || expected_rr_conflicts != -1)
76be9271
PE
646 {
647 if (! src_ok)
035aa4a0
PE
648 complain (ngettext ("expected %d shift/reduce conflict",
649 "expected %d shift/reduce conflicts",
650 src_expected),
651 src_expected);
d6328241 652 if (! rrc_ok)
035aa4a0
PE
653 complain (ngettext ("expected %d reduce/reduce conflict",
654 "expected %d reduce/reduce conflicts",
655 rrc_expected),
656 rrc_expected);
76be9271 657 }
c29240e7
AD
658}
659
660
08089d5d 661void
b408954b 662conflicts_free (void)
08089d5d 663{
afbb696d 664 free (conflicts);
8dd162d3 665 bitset_free (shift_set);
742e4900 666 bitset_free (lookahead_set);
b408954b 667 obstack_free (&solved_conflicts_obstack, NULL);
41d7a5f2 668 obstack_free (&solved_conflicts_xml_obstack, NULL);
08089d5d 669}