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