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 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)
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA
30 #include "conflicts.h"
39 /* -1 stands for not specified. */
40 int expected_sr_conflicts
= -1;
41 int expected_rr_conflicts
= -1;
42 static char *conflicts
;
43 static struct obstack solved_conflicts_obstack
;
45 static bitset shift_set
;
46 static bitset lookahead_set
;
50 enum conflict_resolution
60 /*----------------------------------------------------------------.
61 | Explain how an SR conflict between TOKEN and RULE was resolved: |
63 `----------------------------------------------------------------*/
66 log_resolution (rule
*r
, symbol_number token
,
67 enum conflict_resolution resolution
)
69 if (report_flag
& report_solved_conflicts
)
71 /* The description of the resolution. */
74 case shift_resolution
:
75 case right_resolution
:
76 obstack_fgrow2 (&solved_conflicts_obstack
,
78 Conflict between rule %d and token %s resolved as shift"),
82 case reduce_resolution
:
84 obstack_fgrow2 (&solved_conflicts_obstack
,
86 Conflict between rule %d and token %s resolved as reduce"),
90 case nonassoc_resolution
:
91 obstack_fgrow2 (&solved_conflicts_obstack
,
93 Conflict between rule %d and token %s resolved as an error"),
102 case shift_resolution
:
103 obstack_fgrow2 (&solved_conflicts_obstack
,
106 symbols
[token
]->tag
);
109 case reduce_resolution
:
110 obstack_fgrow2 (&solved_conflicts_obstack
,
116 case left_resolution
:
117 obstack_fgrow1 (&solved_conflicts_obstack
,
119 symbols
[token
]->tag
);
122 case right_resolution
:
123 obstack_fgrow1 (&solved_conflicts_obstack
,
125 symbols
[token
]->tag
);
127 case nonassoc_resolution
:
128 obstack_fgrow1 (&solved_conflicts_obstack
,
130 symbols
[token
]->tag
);
133 obstack_sgrow (&solved_conflicts_obstack
, ".\n");
138 /*------------------------------------------------------------------.
139 | Turn off the shift recorded for the specified token in the |
140 | specified state. Used when we resolve a shift-reduce conflict in |
141 | favor of the reduction or as an error (%nonassoc). |
142 `------------------------------------------------------------------*/
145 flush_shift (state
*s
, int token
)
147 transitions
*trans
= s
->transitions
;
150 bitset_reset (lookahead_set
, token
);
151 for (i
= 0; i
< trans
->num
; i
++)
152 if (!TRANSITION_IS_DISABLED (trans
, i
)
153 && TRANSITION_SYMBOL (trans
, i
) == token
)
154 TRANSITION_DISABLE (trans
, i
);
158 /*--------------------------------------------------------------------.
159 | Turn off the reduce recorded for the specified token in the |
160 | specified lookahead set. Used when we resolve a shift-reduce |
161 | conflict in favor of the shift or as an error (%nonassoc). |
162 `--------------------------------------------------------------------*/
165 flush_reduce (bitset lookahead_tokens
, int token
)
167 bitset_reset (lookahead_tokens
, token
);
171 /*------------------------------------------------------------------.
172 | Attempt to resolve shift-reduce conflict for one rule by means of |
173 | precedence declarations. It has already been checked that the |
174 | rule has a precedence. A conflict is resolved by modifying the |
175 | shift or reduce tables so that there is no longer a conflict. |
177 | RULENO is the number of the lookahead bitset to consider. |
179 | ERRORS and NERRS can be used to store discovered explicit |
181 `------------------------------------------------------------------*/
184 resolve_sr_conflict (state
*s
, int ruleno
, symbol
**errors
, int *nerrs
)
187 reductions
*reds
= s
->reductions
;
188 /* Find the rule to reduce by to get precedence of reduction. */
189 rule
*redrule
= reds
->rules
[ruleno
];
190 int redprec
= redrule
->prec
->prec
;
191 bitset lookahead_tokens
= reds
->lookahead_tokens
[ruleno
];
193 for (i
= 0; i
< ntokens
; i
++)
194 if (bitset_test (lookahead_tokens
, i
)
195 && bitset_test (lookahead_set
, i
)
198 /* Shift-reduce conflict occurs for token number i
199 and it has a precedence.
200 The precedence of shifting is that of token i. */
201 if (symbols
[i
]->prec
< redprec
)
203 log_resolution (redrule
, i
, reduce_resolution
);
206 else if (symbols
[i
]->prec
> redprec
)
208 log_resolution (redrule
, i
, shift_resolution
);
209 flush_reduce (lookahead_tokens
, i
);
212 /* Matching precedence levels.
213 For left association, keep only the reduction.
214 For right association, keep only the shift.
215 For nonassociation, keep neither. */
217 switch (symbols
[i
]->assoc
)
223 log_resolution (redrule
, i
, right_resolution
);
224 flush_reduce (lookahead_tokens
, i
);
228 log_resolution (redrule
, i
, left_resolution
);
233 log_resolution (redrule
, i
, nonassoc_resolution
);
235 flush_reduce (lookahead_tokens
, i
);
236 /* Record an explicit error for this token. */
237 errors
[(*nerrs
)++] = symbols
[i
];
244 /*-------------------------------------------------------------------.
245 | Solve the S/R conflicts of state S using the |
246 | precedence/associativity, and flag it inconsistent if it still has |
247 | conflicts. ERRORS can be used as storage to compute the list of |
248 | lookahead tokens on which S raises a syntax error (%nonassoc). |
249 `-------------------------------------------------------------------*/
252 set_conflicts (state
*s
, symbol
**errors
)
255 transitions
*trans
= s
->transitions
;
256 reductions
*reds
= s
->reductions
;
262 bitset_zero (lookahead_set
);
264 FOR_EACH_SHIFT (trans
, i
)
265 bitset_set (lookahead_set
, TRANSITION_SYMBOL (trans
, i
));
267 /* Loop over all rules which require lookahead in this state. First
268 check for shift-reduce conflict, and try to resolve using
270 for (i
= 0; i
< reds
->num
; ++i
)
271 if (reds
->rules
[i
]->prec
&& reds
->rules
[i
]->prec
->prec
272 && !bitset_disjoint_p (reds
->lookahead_tokens
[i
], lookahead_set
))
273 resolve_sr_conflict (s
, i
, errors
, &nerrs
);
277 /* Some tokens have been explicitly made errors. Allocate a
278 permanent errs structure for this state, to record them. */
279 state_errs_set (s
, nerrs
, errors
);
281 if (obstack_object_size (&solved_conflicts_obstack
))
283 obstack_1grow (&solved_conflicts_obstack
, '\0');
284 s
->solved_conflicts
= obstack_finish (&solved_conflicts_obstack
);
287 /* Loop over all rules which require lookahead in this state. Check
288 for conflicts not resolved above. */
289 for (i
= 0; i
< reds
->num
; ++i
)
291 if (!bitset_disjoint_p (reds
->lookahead_tokens
[i
], lookahead_set
))
292 conflicts
[s
->number
] = 1;
293 bitset_or (lookahead_set
, lookahead_set
, reds
->lookahead_tokens
[i
]);
298 /*----------------------------------------------------------------.
299 | Solve all the S/R conflicts using the precedence/associativity, |
300 | and flag as inconsistent the states that still have conflicts. |
301 `----------------------------------------------------------------*/
304 conflicts_solve (void)
307 /* List of lookahead tokens on which we explicitly raise a syntax error. */
308 symbol
**errors
= xnmalloc (ntokens
+ 1, sizeof *errors
);
310 conflicts
= xcalloc (nstates
, sizeof *conflicts
);
311 shift_set
= bitset_create (ntokens
, BITSET_FIXED
);
312 lookahead_set
= bitset_create (ntokens
, BITSET_FIXED
);
313 obstack_init (&solved_conflicts_obstack
);
315 for (i
= 0; i
< nstates
; i
++)
317 set_conflicts (states
[i
], errors
);
319 /* For uniformity of the code, make sure all the states have a valid
321 if (!states
[i
]->errs
)
322 states
[i
]->errs
= errs_new (0, 0);
330 conflicts_update_state_numbers (state_number old_to_new
[],
331 state_number nstates_old
)
334 for (i
= 0; i
< nstates_old
; ++i
)
335 if (old_to_new
[i
] != nstates_old
)
336 conflicts
[old_to_new
[i
]] = conflicts
[i
];
340 /*---------------------------------------------.
341 | Count the number of shift/reduce conflicts. |
342 `---------------------------------------------*/
345 count_sr_conflicts (state
*s
)
349 transitions
*trans
= s
->transitions
;
350 reductions
*reds
= s
->reductions
;
355 bitset_zero (lookahead_set
);
356 bitset_zero (shift_set
);
358 FOR_EACH_SHIFT (trans
, i
)
359 bitset_set (shift_set
, TRANSITION_SYMBOL (trans
, i
));
361 for (i
= 0; i
< reds
->num
; ++i
)
362 bitset_or (lookahead_set
, lookahead_set
, reds
->lookahead_tokens
[i
]);
364 bitset_and (lookahead_set
, lookahead_set
, shift_set
);
366 src_count
= bitset_count (lookahead_set
);
372 /*----------------------------------------------------------------.
373 | Count the number of reduce/reduce conflicts. If ONE_PER_TOKEN, |
374 | count one conflict for each token that has any reduce/reduce |
375 | conflicts. Otherwise, count one conflict for each pair of |
376 | conflicting reductions. |
377 +`----------------------------------------------------------------*/
380 count_rr_conflicts (state
*s
, bool one_per_token
)
383 reductions
*reds
= s
->reductions
;
386 for (i
= 0; i
< ntokens
; i
++)
390 for (j
= 0; j
< reds
->num
; ++j
)
391 if (bitset_test (reds
->lookahead_tokens
[j
], i
))
395 rrc_count
+= one_per_token
? 1 : count
-1;
402 /*--------------------------------------------------------.
403 | Report the number of conflicts, using the Yacc format. |
404 `--------------------------------------------------------*/
407 conflict_report (FILE *out
, int src_num
, int rrc_num
)
409 if (src_num
&& rrc_num
)
410 fprintf (out
, _("conflicts: %d shift/reduce, %d reduce/reduce\n"),
413 fprintf (out
, _("conflicts: %d shift/reduce\n"), src_num
);
415 fprintf (out
, _("conflicts: %d reduce/reduce\n"), rrc_num
);
419 /*-----------------------------------------------------------.
420 | Output the detailed description of states with conflicts. |
421 `-----------------------------------------------------------*/
424 conflicts_output (FILE *out
)
426 bool printed_sth
= false;
428 for (i
= 0; i
< nstates
; i
++)
430 state
*s
= states
[i
];
433 fprintf (out
, _("State %d "), i
);
434 conflict_report (out
, count_sr_conflicts (s
),
435 count_rr_conflicts (s
, true));
443 /*--------------------------------------------------------.
444 | Total the number of S/R and R/R conflicts. Unlike the |
445 | code in conflicts_output, however, count EACH pair of |
446 | reductions for the same state and lookahead as one |
448 `--------------------------------------------------------*/
451 conflicts_total_count (void)
456 /* Conflicts by state. */
458 for (i
= 0; i
< nstates
; i
++)
461 count
+= count_sr_conflicts (states
[i
]);
462 count
+= count_rr_conflicts (states
[i
], false);
468 /*------------------------------------------.
469 | Reporting the total number of conflicts. |
470 `------------------------------------------*/
473 conflicts_print (void)
475 /* Is the number of SR conflicts OK? Either EXPECTED_CONFLICTS is
476 not set, and then we want 0 SR, or else it is specified, in which
477 case we want equality. */
486 /* Conflicts by state. */
490 for (i
= 0; i
< nstates
; i
++)
493 src_total
+= count_sr_conflicts (states
[i
]);
494 rrc_total
+= count_rr_conflicts (states
[i
], true);
498 if (! glr_parser
&& rrc_total
> 0 && expected_rr_conflicts
!= -1)
500 warn (_("%%expect-rr applies only to GLR parsers"));
501 expected_rr_conflicts
= -1;
504 src_expected
= expected_sr_conflicts
== -1 ? 0 : expected_sr_conflicts
;
505 rrc_expected
= expected_rr_conflicts
== -1 ? 0 : expected_rr_conflicts
;
506 src_ok
= src_total
== src_expected
;
507 rrc_ok
= rrc_total
== rrc_expected
;
509 /* If there are as many RR conflicts and SR conflicts as
510 expected, then there is nothing to report. */
514 /* Report the total number of conflicts on STDERR. */
515 if (src_total
| rrc_total
)
518 fprintf (stderr
, "%s: ", current_file
);
519 conflict_report (stderr
, src_total
, rrc_total
);
522 if (expected_sr_conflicts
!= -1 || expected_rr_conflicts
!= -1)
525 complain (ngettext ("expected %d shift/reduce conflict",
526 "expected %d shift/reduce conflicts",
530 complain (ngettext ("expected %d reduce/reduce conflict",
531 "expected %d reduce/reduce conflicts",
539 conflicts_free (void)
542 bitset_free (shift_set
);
543 bitset_free (lookahead_set
);
544 obstack_free (&solved_conflicts_obstack
, NULL
);