]> git.saurik.com Git - bison.git/blame - src/conflicts.c
Update from GFDL GFDL 1.2 to 1.3.
[bison.git] / src / conflicts.c
CommitLineData
742e4900 1/* Find and resolve or report lookahead conflicts for bison,
f041e30b 2
1462fcee
JD
3 Copyright (C) 1984, 1989, 1992, 2000-2007, 2009-2010 Free Software
4 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");
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
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
676385e2
PH
525/*--------------------------------------------------------.
526| Total the number of S/R and R/R conflicts. Unlike the |
527| code in conflicts_output, however, count EACH pair of |
742e4900 528| reductions for the same state and lookahead as one |
676385e2
PH
529| conflict. |
530`--------------------------------------------------------*/
531
532int
533conflicts_total_count (void)
534{
f041e30b 535 state_number i;
676385e2
PH
536 int count;
537
538 /* Conflicts by state. */
539 count = 0;
540 for (i = 0; i < nstates; i++)
541 if (conflicts[i])
542 {
543 count += count_sr_conflicts (states[i]);
8307162d 544 count += count_rr_conflicts (states[i], false);
676385e2
PH
545 }
546 return count;
547}
e0e5bf84 548
c29240e7 549
0df87bb6
AD
550/*------------------------------------------.
551| Reporting the total number of conflicts. |
552`------------------------------------------*/
0619caf0 553
0df87bb6
AD
554void
555conflicts_print (void)
556{
a034c8b8
AD
557 /* Is the number of SR conflicts OK? Either EXPECTED_CONFLICTS is
558 not set, and then we want 0 SR, or else it is specified, in which
559 case we want equality. */
035aa4a0
PE
560 bool src_ok;
561 bool rrc_ok;
a034c8b8 562
0df87bb6
AD
563 int src_total = 0;
564 int rrc_total = 0;
035aa4a0
PE
565 int src_expected;
566 int rrc_expected;
0df87bb6
AD
567
568 /* Conflicts by state. */
d57650a5 569 {
f041e30b 570 state_number i;
d57650a5
AD
571
572 for (i = 0; i < nstates; i++)
573 if (conflicts[i])
574 {
575 src_total += count_sr_conflicts (states[i]);
8307162d 576 rrc_total += count_rr_conflicts (states[i], true);
d57650a5
AD
577 }
578 }
c29240e7 579
d6328241
PH
580 if (! glr_parser && rrc_total > 0 && expected_rr_conflicts != -1)
581 {
4f16766c 582 warn (_("%%expect-rr applies only to GLR parsers"));
d6328241
PH
583 expected_rr_conflicts = -1;
584 }
585
035aa4a0
PE
586 src_expected = expected_sr_conflicts == -1 ? 0 : expected_sr_conflicts;
587 rrc_expected = expected_rr_conflicts == -1 ? 0 : expected_rr_conflicts;
588 src_ok = src_total == src_expected;
589 rrc_ok = rrc_total == rrc_expected;
a034c8b8 590
d6328241 591 /* If there are as many RR conflicts and SR conflicts as
a034c8b8 592 expected, then there is nothing to report. */
035aa4a0 593 if (rrc_ok & src_ok)
a034c8b8
AD
594 return;
595
0619caf0 596 /* Report the total number of conflicts on STDERR. */
035aa4a0
PE
597 if (src_total | rrc_total)
598 {
599 if (! yacc_flag)
600 fprintf (stderr, "%s: ", current_file);
601 conflict_report (stderr, src_total, rrc_total);
602 }
7da99ede 603
d6328241 604 if (expected_sr_conflicts != -1 || expected_rr_conflicts != -1)
76be9271
PE
605 {
606 if (! src_ok)
035aa4a0
PE
607 complain (ngettext ("expected %d shift/reduce conflict",
608 "expected %d shift/reduce conflicts",
609 src_expected),
610 src_expected);
d6328241 611 if (! rrc_ok)
035aa4a0
PE
612 complain (ngettext ("expected %d reduce/reduce conflict",
613 "expected %d reduce/reduce conflicts",
614 rrc_expected),
615 rrc_expected);
76be9271 616 }
c29240e7
AD
617}
618
619
08089d5d 620void
b408954b 621conflicts_free (void)
08089d5d 622{
afbb696d 623 free (conflicts);
8dd162d3 624 bitset_free (shift_set);
742e4900 625 bitset_free (lookahead_set);
b408954b 626 obstack_free (&solved_conflicts_obstack, NULL);
41d7a5f2 627 obstack_free (&solved_conflicts_xml_obstack, NULL);
08089d5d 628}