1 /* Find and resolve or report lookahead conflicts for bison,
3 Copyright (C) 1984, 1989, 1992, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4 2007 Free Software Foundation, Inc.
6 This file is part of Bison, the GNU Compiler Compiler.
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.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
28 #include "conflicts.h"
37 /* -1 stands for not specified. */
38 int expected_sr_conflicts
= -1;
39 int expected_rr_conflicts
= -1;
40 static char *conflicts
;
41 static struct obstack solved_conflicts_obstack
;
43 static bitset shift_set
;
44 static bitset lookahead_set
;
48 enum conflict_resolution
58 /*----------------------------------------------------------------.
59 | Explain how an SR conflict between TOKEN and RULE was resolved: |
61 `----------------------------------------------------------------*/
64 log_resolution (rule
*r
, symbol_number token
,
65 enum conflict_resolution resolution
)
67 if (report_flag
& report_solved_conflicts
)
69 /* The description of the resolution. */
72 case shift_resolution
:
73 case right_resolution
:
74 obstack_fgrow2 (&solved_conflicts_obstack
,
76 Conflict between rule %d and token %s resolved as shift"),
80 case reduce_resolution
:
82 obstack_fgrow2 (&solved_conflicts_obstack
,
84 Conflict between rule %d and token %s resolved as reduce"),
88 case nonassoc_resolution
:
89 obstack_fgrow2 (&solved_conflicts_obstack
,
91 Conflict between rule %d and token %s resolved as an error"),
100 case shift_resolution
:
101 obstack_fgrow2 (&solved_conflicts_obstack
,
104 symbols
[token
]->tag
);
107 case reduce_resolution
:
108 obstack_fgrow2 (&solved_conflicts_obstack
,
114 case left_resolution
:
115 obstack_fgrow1 (&solved_conflicts_obstack
,
117 symbols
[token
]->tag
);
120 case right_resolution
:
121 obstack_fgrow1 (&solved_conflicts_obstack
,
123 symbols
[token
]->tag
);
125 case nonassoc_resolution
:
126 obstack_fgrow1 (&solved_conflicts_obstack
,
128 symbols
[token
]->tag
);
131 obstack_sgrow (&solved_conflicts_obstack
, ".\n");
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 or as an error (%nonassoc). |
140 `------------------------------------------------------------------*/
143 flush_shift (state
*s
, int token
)
145 transitions
*trans
= s
->transitions
;
148 bitset_reset (lookahead_set
, token
);
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
);
156 /*--------------------------------------------------------------------.
157 | Turn off the reduce recorded for the specified token in the |
158 | specified lookahead set. Used when we resolve a shift-reduce |
159 | conflict in favor of the shift or as an error (%nonassoc). |
160 `--------------------------------------------------------------------*/
163 flush_reduce (bitset lookahead_tokens
, int token
)
165 bitset_reset (lookahead_tokens
, token
);
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. |
175 | RULENO is the number of the lookahead bitset to consider. |
177 | ERRORS and NERRS can be used to store discovered explicit |
179 `------------------------------------------------------------------*/
182 resolve_sr_conflict (state
*s
, int ruleno
, symbol
**errors
, int *nerrs
)
185 reductions
*reds
= s
->reductions
;
186 /* Find the rule to reduce by to get precedence of reduction. */
187 rule
*redrule
= reds
->rules
[ruleno
];
188 int redprec
= redrule
->prec
->prec
;
189 bitset lookahead_tokens
= reds
->lookahead_tokens
[ruleno
];
191 for (i
= 0; i
< ntokens
; i
++)
192 if (bitset_test (lookahead_tokens
, i
)
193 && bitset_test (lookahead_set
, i
)
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. */
199 if (symbols
[i
]->prec
< redprec
)
201 log_resolution (redrule
, i
, reduce_resolution
);
204 else if (symbols
[i
]->prec
> redprec
)
206 log_resolution (redrule
, i
, shift_resolution
);
207 flush_reduce (lookahead_tokens
, i
);
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. */
215 switch (symbols
[i
]->assoc
)
221 log_resolution (redrule
, i
, right_resolution
);
222 flush_reduce (lookahead_tokens
, i
);
226 log_resolution (redrule
, i
, left_resolution
);
231 log_resolution (redrule
, i
, nonassoc_resolution
);
233 flush_reduce (lookahead_tokens
, i
);
234 /* Record an explicit error for this token. */
235 errors
[(*nerrs
)++] = symbols
[i
];
242 /*-------------------------------------------------------------------.
243 | Solve the S/R conflicts of state S using the |
244 | precedence/associativity, and flag it inconsistent if it still has |
245 | conflicts. ERRORS can be used as storage to compute the list of |
246 | lookahead tokens on which S raises a syntax error (%nonassoc). |
247 `-------------------------------------------------------------------*/
250 set_conflicts (state
*s
, symbol
**errors
)
253 transitions
*trans
= s
->transitions
;
254 reductions
*reds
= s
->reductions
;
260 bitset_zero (lookahead_set
);
262 FOR_EACH_SHIFT (trans
, i
)
263 bitset_set (lookahead_set
, TRANSITION_SYMBOL (trans
, i
));
265 /* Loop over all rules which require lookahead in this state. First
266 check for shift-reduce conflict, and try to resolve using
268 for (i
= 0; i
< reds
->num
; ++i
)
269 if (reds
->rules
[i
]->prec
&& reds
->rules
[i
]->prec
->prec
270 && !bitset_disjoint_p (reds
->lookahead_tokens
[i
], lookahead_set
))
271 resolve_sr_conflict (s
, i
, errors
, &nerrs
);
275 /* Some tokens have been explicitly made errors. Allocate a
276 permanent errs structure for this state, to record them. */
277 state_errs_set (s
, nerrs
, errors
);
279 if (obstack_object_size (&solved_conflicts_obstack
))
281 obstack_1grow (&solved_conflicts_obstack
, '\0');
282 s
->solved_conflicts
= obstack_finish (&solved_conflicts_obstack
);
285 /* Loop over all rules which require lookahead in this state. Check
286 for conflicts not resolved above. */
287 for (i
= 0; i
< reds
->num
; ++i
)
289 if (!bitset_disjoint_p (reds
->lookahead_tokens
[i
], lookahead_set
))
290 conflicts
[s
->number
] = 1;
291 bitset_or (lookahead_set
, lookahead_set
, reds
->lookahead_tokens
[i
]);
296 /*----------------------------------------------------------------.
297 | Solve all the S/R conflicts using the precedence/associativity, |
298 | and flag as inconsistent the states that still have conflicts. |
299 `----------------------------------------------------------------*/
302 conflicts_solve (void)
305 /* List of lookahead tokens on which we explicitly raise a syntax error. */
306 symbol
**errors
= xnmalloc (ntokens
+ 1, sizeof *errors
);
308 conflicts
= xcalloc (nstates
, sizeof *conflicts
);
309 shift_set
= bitset_create (ntokens
, BITSET_FIXED
);
310 lookahead_set
= bitset_create (ntokens
, BITSET_FIXED
);
311 obstack_init (&solved_conflicts_obstack
);
313 for (i
= 0; i
< nstates
; i
++)
315 set_conflicts (states
[i
], errors
);
317 /* For uniformity of the code, make sure all the states have a valid
319 if (!states
[i
]->errs
)
320 states
[i
]->errs
= errs_new (0, 0);
328 conflicts_update_state_numbers (state_number old_to_new
[],
329 state_number nstates_old
)
332 for (i
= 0; i
< nstates_old
; ++i
)
333 if (old_to_new
[i
] != nstates_old
)
334 conflicts
[old_to_new
[i
]] = conflicts
[i
];
338 /*---------------------------------------------.
339 | Count the number of shift/reduce conflicts. |
340 `---------------------------------------------*/
343 count_sr_conflicts (state
*s
)
347 transitions
*trans
= s
->transitions
;
348 reductions
*reds
= s
->reductions
;
353 bitset_zero (lookahead_set
);
354 bitset_zero (shift_set
);
356 FOR_EACH_SHIFT (trans
, i
)
357 bitset_set (shift_set
, TRANSITION_SYMBOL (trans
, i
));
359 for (i
= 0; i
< reds
->num
; ++i
)
360 bitset_or (lookahead_set
, lookahead_set
, reds
->lookahead_tokens
[i
]);
362 bitset_and (lookahead_set
, lookahead_set
, shift_set
);
364 src_count
= bitset_count (lookahead_set
);
370 /*----------------------------------------------------------------.
371 | Count the number of reduce/reduce conflicts. If ONE_PER_TOKEN, |
372 | count one conflict for each token that has any reduce/reduce |
373 | conflicts. Otherwise, count one conflict for each pair of |
374 | conflicting reductions. |
375 +`----------------------------------------------------------------*/
378 count_rr_conflicts (state
*s
, bool one_per_token
)
381 reductions
*reds
= s
->reductions
;
384 for (i
= 0; i
< ntokens
; i
++)
388 for (j
= 0; j
< reds
->num
; ++j
)
389 if (bitset_test (reds
->lookahead_tokens
[j
], i
))
393 rrc_count
+= one_per_token
? 1 : count
-1;
400 /*--------------------------------------------------------.
401 | Report the number of conflicts, using the Yacc format. |
402 `--------------------------------------------------------*/
405 conflict_report (FILE *out
, int src_num
, int rrc_num
)
407 if (src_num
&& rrc_num
)
408 fprintf (out
, _("conflicts: %d shift/reduce, %d reduce/reduce\n"),
411 fprintf (out
, _("conflicts: %d shift/reduce\n"), src_num
);
413 fprintf (out
, _("conflicts: %d reduce/reduce\n"), rrc_num
);
417 /*-----------------------------------------------------------.
418 | Output the detailed description of states with conflicts. |
419 `-----------------------------------------------------------*/
422 conflicts_output (FILE *out
)
424 bool printed_sth
= false;
426 for (i
= 0; i
< nstates
; i
++)
428 state
*s
= states
[i
];
431 fprintf (out
, _("State %d "), i
);
432 conflict_report (out
, count_sr_conflicts (s
),
433 count_rr_conflicts (s
, true));
441 /*--------------------------------------------------------.
442 | Total the number of S/R and R/R conflicts. Unlike the |
443 | code in conflicts_output, however, count EACH pair of |
444 | reductions for the same state and lookahead as one |
446 `--------------------------------------------------------*/
449 conflicts_total_count (void)
454 /* Conflicts by state. */
456 for (i
= 0; i
< nstates
; i
++)
459 count
+= count_sr_conflicts (states
[i
]);
460 count
+= count_rr_conflicts (states
[i
], false);
466 /*------------------------------------------.
467 | Reporting the total number of conflicts. |
468 `------------------------------------------*/
471 conflicts_print (void)
473 /* Is the number of SR conflicts OK? Either EXPECTED_CONFLICTS is
474 not set, and then we want 0 SR, or else it is specified, in which
475 case we want equality. */
484 /* Conflicts by state. */
488 for (i
= 0; i
< nstates
; i
++)
491 src_total
+= count_sr_conflicts (states
[i
]);
492 rrc_total
+= count_rr_conflicts (states
[i
], true);
496 if (! glr_parser
&& rrc_total
> 0 && expected_rr_conflicts
!= -1)
498 warn (_("%%expect-rr applies only to GLR parsers"));
499 expected_rr_conflicts
= -1;
502 src_expected
= expected_sr_conflicts
== -1 ? 0 : expected_sr_conflicts
;
503 rrc_expected
= expected_rr_conflicts
== -1 ? 0 : expected_rr_conflicts
;
504 src_ok
= src_total
== src_expected
;
505 rrc_ok
= rrc_total
== rrc_expected
;
507 /* If there are as many RR conflicts and SR conflicts as
508 expected, then there is nothing to report. */
512 /* Report the total number of conflicts on STDERR. */
513 if (src_total
| rrc_total
)
516 fprintf (stderr
, "%s: ", current_file
);
517 conflict_report (stderr
, src_total
, rrc_total
);
520 if (expected_sr_conflicts
!= -1 || expected_rr_conflicts
!= -1)
523 complain (ngettext ("expected %d shift/reduce conflict",
524 "expected %d shift/reduce conflicts",
528 complain (ngettext ("expected %d reduce/reduce conflict",
529 "expected %d reduce/reduce conflicts",
537 conflicts_free (void)
540 bitset_free (shift_set
);
541 bitset_free (lookahead_set
);
542 obstack_free (&solved_conflicts_obstack
, NULL
);