]> git.saurik.com Git - bison.git/blame - src/conflicts.c
doc: clean up references to `Tracking Locations'.
[bison.git] / src / conflicts.c
CommitLineData
742e4900 1/* Find and resolve or report lookahead conflicts for bison,
f041e30b 2
575619af
JD
3 Copyright (C) 1984, 1989, 1992, 2000-2011 Free Software Foundation,
4 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");
ef1b4273 138 }
41d7a5f2 139
ef1b4273
JD
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_fgrow2 (&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_fgrow2 (&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_fgrow2 (&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 }
41d7a5f2 172
ef1b4273
JD
173 /* The reason. */
174 switch (resolution)
175 {
176 case shift_resolution:
177 obstack_fgrow2 (&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_fgrow2 (&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_fgrow1 (&solved_conflicts_xml_obstack,
192 "%%left %s",
193 xml_escape (symbols[token]->tag));
194 break;
195
196 case right_resolution:
197 obstack_fgrow1 (&solved_conflicts_xml_obstack,
198 "%%right %s",
199 xml_escape (symbols[token]->tag));
200 break;
201
202 case nonassoc_resolution:
203 obstack_fgrow1 (&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");
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
d78f0ac9
AD
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. */
709ae8c6 294
5a670b1e 295 switch (symbols[i]->assoc)
709ae8c6 296 {
d78f0ac9 297 case undef_assoc:
68cae94e
PE
298 abort ();
299
d78f0ac9
AD
300 case precedence_assoc:
301 break;
302
709ae8c6 303 case right_assoc:
9801d40c 304 log_resolution (redrule, i, right_resolution);
742e4900 305 flush_reduce (lookahead_tokens, i);
709ae8c6
AD
306 break;
307
308 case left_assoc:
9801d40c 309 log_resolution (redrule, i, left_resolution);
f041e30b 310 flush_shift (s, i);
709ae8c6
AD
311 break;
312
313 case non_assoc:
9801d40c 314 log_resolution (redrule, i, nonassoc_resolution);
f041e30b 315 flush_shift (s, i);
742e4900 316 flush_reduce (lookahead_tokens, i);
709ae8c6 317 /* Record an explicit error for this token. */
9d774aff 318 errors[(*nerrs)++] = symbols[i];
709ae8c6
AD
319 break;
320 }
92b16366 321 }
08089d5d
DM
322}
323
324
8b752b00 325/*-------------------------------------------------------------------.
f041e30b 326| Solve the S/R conflicts of state S using the |
8b752b00 327| precedence/associativity, and flag it inconsistent if it still has |
f041e30b 328| conflicts. ERRORS can be used as storage to compute the list of |
742e4900 329| lookahead tokens on which S raises a syntax error (%nonassoc). |
8b752b00
AD
330`-------------------------------------------------------------------*/
331
4a120d45 332static void
f041e30b 333set_conflicts (state *s, symbol **errors)
08089d5d 334{
914feea9 335 int i;
f041e30b
PE
336 transitions *trans = s->transitions;
337 reductions *reds = s->reductions;
9d774aff 338 int nerrs = 0;
c29240e7 339
f041e30b 340 if (s->consistent)
c29240e7 341 return;
08089d5d 342
742e4900 343 bitset_zero (lookahead_set);
08089d5d 344
f041e30b 345 FOR_EACH_SHIFT (trans, i)
742e4900 346 bitset_set (lookahead_set, TRANSITION_SYMBOL (trans, i));
08089d5d 347
742e4900 348 /* Loop over all rules which require lookahead in this state. First
c29240e7 349 check for shift-reduce conflict, and try to resolve using
9801d40c 350 precedence. */
cd08e51e
AD
351 for (i = 0; i < reds->num; ++i)
352 if (reds->rules[i]->prec && reds->rules[i]->prec->prec
742e4900 353 && !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
9d774aff
JD
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 {
364 obstack_1grow (&solved_conflicts_obstack, '\0');
365 s->solved_conflicts = obstack_finish (&solved_conflicts_obstack);
366 }
41d7a5f2
PE
367 if (obstack_object_size (&solved_conflicts_xml_obstack))
368 {
369 obstack_1grow (&solved_conflicts_xml_obstack, '\0');
370 s->solved_conflicts_xml = obstack_finish (&solved_conflicts_xml_obstack);
371 }
08089d5d 372
742e4900 373 /* Loop over all rules which require lookahead in this state. Check
c29240e7 374 for conflicts not resolved above. */
cd08e51e 375 for (i = 0; i < reds->num; ++i)
08089d5d 376 {
742e4900 377 if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
f041e30b 378 conflicts[s->number] = 1;
742e4900 379 bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
c29240e7
AD
380 }
381}
08089d5d 382
8b752b00
AD
383
384/*----------------------------------------------------------------.
385| Solve all the S/R conflicts using the precedence/associativity, |
386| and flag as inconsistent the states that still have conflicts. |
387`----------------------------------------------------------------*/
388
08089d5d 389void
b408954b 390conflicts_solve (void)
08089d5d 391{
f041e30b 392 state_number i;
742e4900 393 /* List of lookahead tokens on which we explicitly raise a syntax error. */
da2a7671 394 symbol **errors = xnmalloc (ntokens + 1, sizeof *errors);
08089d5d 395
da2a7671 396 conflicts = xcalloc (nstates, sizeof *conflicts);
8dd162d3 397 shift_set = bitset_create (ntokens, BITSET_FIXED);
742e4900 398 lookahead_set = bitset_create (ntokens, BITSET_FIXED);
b408954b 399 obstack_init (&solved_conflicts_obstack);
41d7a5f2 400 obstack_init (&solved_conflicts_xml_obstack);
08089d5d 401
c29240e7 402 for (i = 0; i < nstates; i++)
8b752b00 403 {
f041e30b 404 set_conflicts (states[i], errors);
8b752b00
AD
405
406 /* For uniformity of the code, make sure all the states have a valid
407 `errs' member. */
408 if (!states[i]->errs)
409 states[i]->errs = errs_new (0, 0);
410 }
411
f041e30b 412 free (errors);
08089d5d
DM
413}
414
415
5967f0cf
JD
416void
417conflicts_update_state_numbers (state_number old_to_new[],
418 state_number nstates_old)
419{
14462c2b
JD
420 state_number i;
421 for (i = 0; i < nstates_old; ++i)
5967f0cf
JD
422 if (old_to_new[i] != nstates_old)
423 conflicts[old_to_new[i]] = conflicts[i];
424}
425
426
c29240e7
AD
427/*---------------------------------------------.
428| Count the number of shift/reduce conflicts. |
429`---------------------------------------------*/
430
0df87bb6 431static int
f041e30b 432count_sr_conflicts (state *s)
08089d5d 433{
f9abaa2c 434 int i;
0df87bb6 435 int src_count = 0;
f041e30b
PE
436 transitions *trans = s->transitions;
437 reductions *reds = s->reductions;
08089d5d 438
f041e30b 439 if (!trans)
0df87bb6 440 return 0;
08089d5d 441
742e4900 442 bitset_zero (lookahead_set);
8dd162d3 443 bitset_zero (shift_set);
08089d5d 444
f041e30b 445 FOR_EACH_SHIFT (trans, i)
8dd162d3 446 bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
08089d5d 447
cd08e51e 448 for (i = 0; i < reds->num; ++i)
742e4900 449 bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
08089d5d 450
742e4900 451 bitset_and (lookahead_set, lookahead_set, shift_set);
08089d5d 452
742e4900 453 src_count = bitset_count (lookahead_set);
0df87bb6
AD
454
455 return src_count;
08089d5d
DM
456}
457
458
676385e2
PH
459/*----------------------------------------------------------------.
460| Count the number of reduce/reduce conflicts. If ONE_PER_TOKEN, |
461| count one conflict for each token that has any reduce/reduce |
462| conflicts. Otherwise, count one conflict for each pair of |
463| conflicting reductions. |
464+`----------------------------------------------------------------*/
c29240e7 465
0df87bb6 466static int
d0829076 467count_rr_conflicts (state *s, bool one_per_token)
08089d5d 468{
c29240e7 469 int i;
f041e30b 470 reductions *reds = s->reductions;
0df87bb6 471 int rrc_count = 0;
08089d5d 472
08089d5d
DM
473 for (i = 0; i < ntokens; i++)
474 {
0df87bb6
AD
475 int count = 0;
476 int j;
cd08e51e 477 for (j = 0; j < reds->num; ++j)
742e4900 478 if (bitset_test (reds->lookahead_tokens[j], i))
52afa962 479 count++;
08089d5d 480
c29240e7 481 if (count >= 2)
676385e2 482 rrc_count += one_per_token ? 1 : count-1;
08089d5d 483 }
0df87bb6
AD
484
485 return rrc_count;
08089d5d
DM
486}
487
52489d44 488
be728048
PE
489/*--------------------------------------------------------.
490| Report the number of conflicts, using the Yacc format. |
491`--------------------------------------------------------*/
52489d44
AD
492
493static void
be728048 494conflict_report (FILE *out, int src_num, int rrc_num)
52489d44 495{
be728048
PE
496 if (src_num && rrc_num)
497 fprintf (out, _("conflicts: %d shift/reduce, %d reduce/reduce\n"),
498 src_num, rrc_num);
499 else if (src_num)
500 fprintf (out, _("conflicts: %d shift/reduce\n"), src_num);
501 else if (rrc_num)
502 fprintf (out, _("conflicts: %d reduce/reduce\n"), rrc_num);
52489d44
AD
503}
504
505
0df87bb6
AD
506/*-----------------------------------------------------------.
507| Output the detailed description of states with conflicts. |
508`-----------------------------------------------------------*/
c29240e7
AD
509
510void
0df87bb6 511conflicts_output (FILE *out)
c29240e7 512{
8307162d 513 bool printed_sth = false;
f041e30b 514 state_number i;
0df87bb6 515 for (i = 0; i < nstates; i++)
640748ee 516 {
f041e30b 517 state *s = states[i];
640748ee
AD
518 if (conflicts[i])
519 {
be728048
PE
520 fprintf (out, _("State %d "), i);
521 conflict_report (out, count_sr_conflicts (s),
522 count_rr_conflicts (s, true));
8307162d 523 printed_sth = true;
640748ee
AD
524 }
525 }
d2d1b42b
AD
526 if (printed_sth)
527 fputs ("\n\n", out);
0df87bb6 528}
c29240e7 529
676385e2
PH
530/*--------------------------------------------------------.
531| Total the number of S/R and R/R conflicts. Unlike the |
532| code in conflicts_output, however, count EACH pair of |
742e4900 533| reductions for the same state and lookahead as one |
676385e2
PH
534| conflict. |
535`--------------------------------------------------------*/
536
537int
538conflicts_total_count (void)
539{
f041e30b 540 state_number i;
676385e2
PH
541 int count;
542
543 /* Conflicts by state. */
544 count = 0;
545 for (i = 0; i < nstates; i++)
546 if (conflicts[i])
547 {
548 count += count_sr_conflicts (states[i]);
8307162d 549 count += count_rr_conflicts (states[i], false);
676385e2
PH
550 }
551 return count;
552}
e0e5bf84 553
c29240e7 554
0df87bb6
AD
555/*------------------------------------------.
556| Reporting the total number of conflicts. |
557`------------------------------------------*/
0619caf0 558
0df87bb6
AD
559void
560conflicts_print (void)
561{
a034c8b8
AD
562 /* Is the number of SR conflicts OK? Either EXPECTED_CONFLICTS is
563 not set, and then we want 0 SR, or else it is specified, in which
564 case we want equality. */
035aa4a0
PE
565 bool src_ok;
566 bool rrc_ok;
a034c8b8 567
0df87bb6
AD
568 int src_total = 0;
569 int rrc_total = 0;
035aa4a0
PE
570 int src_expected;
571 int rrc_expected;
0df87bb6
AD
572
573 /* Conflicts by state. */
d57650a5 574 {
f041e30b 575 state_number i;
d57650a5
AD
576
577 for (i = 0; i < nstates; i++)
578 if (conflicts[i])
579 {
580 src_total += count_sr_conflicts (states[i]);
8307162d 581 rrc_total += count_rr_conflicts (states[i], true);
d57650a5
AD
582 }
583 }
c29240e7 584
d6328241
PH
585 if (! glr_parser && rrc_total > 0 && expected_rr_conflicts != -1)
586 {
4f16766c 587 warn (_("%%expect-rr applies only to GLR parsers"));
d6328241
PH
588 expected_rr_conflicts = -1;
589 }
590
035aa4a0
PE
591 src_expected = expected_sr_conflicts == -1 ? 0 : expected_sr_conflicts;
592 rrc_expected = expected_rr_conflicts == -1 ? 0 : expected_rr_conflicts;
593 src_ok = src_total == src_expected;
594 rrc_ok = rrc_total == rrc_expected;
a034c8b8 595
d6328241 596 /* If there are as many RR conflicts and SR conflicts as
a034c8b8 597 expected, then there is nothing to report. */
035aa4a0 598 if (rrc_ok & src_ok)
a034c8b8
AD
599 return;
600
0619caf0 601 /* Report the total number of conflicts on STDERR. */
786743d5
JD
602 if (expected_sr_conflicts == -1 && expected_rr_conflicts == -1)
603 {
604 if (!(warnings_flag & warnings_conflicts_sr))
605 src_total = 0;
606 if (!(warnings_flag & warnings_conflicts_rr))
607 rrc_total = 0;
608 }
035aa4a0
PE
609 if (src_total | rrc_total)
610 {
786743d5
JD
611 if (expected_sr_conflicts == -1 && expected_rr_conflicts == -1)
612 set_warning_issued ();
035aa4a0
PE
613 if (! yacc_flag)
614 fprintf (stderr, "%s: ", current_file);
615 conflict_report (stderr, src_total, rrc_total);
616 }
7da99ede 617
d6328241 618 if (expected_sr_conflicts != -1 || expected_rr_conflicts != -1)
76be9271
PE
619 {
620 if (! src_ok)
035aa4a0
PE
621 complain (ngettext ("expected %d shift/reduce conflict",
622 "expected %d shift/reduce conflicts",
623 src_expected),
624 src_expected);
d6328241 625 if (! rrc_ok)
035aa4a0
PE
626 complain (ngettext ("expected %d reduce/reduce conflict",
627 "expected %d reduce/reduce conflicts",
628 rrc_expected),
629 rrc_expected);
76be9271 630 }
c29240e7
AD
631}
632
633
08089d5d 634void
b408954b 635conflicts_free (void)
08089d5d 636{
afbb696d 637 free (conflicts);
8dd162d3 638 bitset_free (shift_set);
742e4900 639 bitset_free (lookahead_set);
b408954b 640 obstack_free (&solved_conflicts_obstack, NULL);
41d7a5f2 641 obstack_free (&solved_conflicts_xml_obstack, NULL);
08089d5d 642}