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