]> git.saurik.com Git - bison.git/blob - src/conflicts.c
Comment wording fix.
[bison.git] / src / conflicts.c
1 /* Find and resolve or report look-ahead conflicts for bison,
2
3 Copyright (C) 1984, 1989, 1992, 2000, 2001, 2002
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. */
39 int expected_conflicts = -1;
40 static char *conflicts = NULL;
41 struct obstack solved_conflicts_obstack;
42
43 static bitset shiftset;
44 static bitset lookaheadset;
45
46 \f
47
48 enum conflict_resolution
49 {
50 shift_resolution,
51 reduce_resolution,
52 left_resolution,
53 right_resolution,
54 nonassoc_resolution
55 };
56
57
58 /*----------------------------------------------------------------.
59 | Explain how an SR conflict between TOKEN and RULE was resolved: |
60 | RESOLUTION. |
61 `----------------------------------------------------------------*/
62
63 static inline void
64 log_resolution (rule *r, symbol_number token,
65 enum conflict_resolution resolution)
66 {
67 if (report_flag & report_solved_conflicts)
68 {
69 /* The description of the resolution. */
70 switch (resolution)
71 {
72 case shift_resolution:
73 case right_resolution:
74 obstack_fgrow2 (&solved_conflicts_obstack,
75 _("\
76 Conflict between rule %d and token %s resolved as shift"),
77 r->number,
78 symbols[token]->tag);
79 break;
80 case reduce_resolution:
81 case left_resolution:
82 obstack_fgrow2 (&solved_conflicts_obstack,
83 _("\
84 Conflict between rule %d and token %s resolved as reduce"),
85 r->number,
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"),
92 r->number,
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)",
103 r->prec->tag,
104 symbols[token]->tag);
105 break;
106
107 case reduce_resolution:
108 obstack_fgrow2 (&solved_conflicts_obstack,
109 " (%s < %s)",
110 symbols[token]->tag,
111 r->prec->tag);
112 break;
113
114 case left_resolution:
115 obstack_fgrow1 (&solved_conflicts_obstack,
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 }
133 }
134
135
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
142 static void
143 flush_shift (state *s, int token)
144 {
145 transitions *trans = s->transitions;
146 int i;
147
148 bitset_reset (lookaheadset, 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);
153 }
154
155
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
162 static void
163 flush_reduce (bitset lookaheads, int token)
164 {
165 bitset_reset (lookaheads, token);
166 }
167
168
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. |
174 | |
175 | LOOKAHEAD is the number of the lookahead bitset to consider. |
176 | |
177 | ERRORS can be used to store discovered explicit errors. |
178 `------------------------------------------------------------------*/
179
180 static void
181 resolve_sr_conflict (state *s, int ruleno, symbol **errors)
182 {
183 symbol_number i;
184 reductions *reds = s->reductions;
185 /* Find the rule to reduce by to get precedence of reduction. */
186 rule *redrule = reds->rules[ruleno];
187 int redprec = redrule->prec->prec;
188 bitset lookaheads = reds->lookaheads[ruleno];
189 int nerrs = 0;
190
191 for (i = 0; i < ntokens; i++)
192 if (bitset_test (lookaheads, i)
193 && bitset_test (lookaheadset, i)
194 && symbols[i]->prec)
195 {
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)
200 {
201 log_resolution (redrule, i, reduce_resolution);
202 flush_shift (s, i);
203 }
204 else if (symbols[i]->prec > redprec)
205 {
206 log_resolution (redrule, i, shift_resolution);
207 flush_reduce (lookaheads, i);
208 }
209 else
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
215 switch (symbols[i]->assoc)
216 {
217 case right_assoc:
218 log_resolution (redrule, i, right_resolution);
219 flush_reduce (lookaheads, i);
220 break;
221
222 case left_assoc:
223 log_resolution (redrule, i, left_resolution);
224 flush_shift (s, i);
225 break;
226
227 case non_assoc:
228 log_resolution (redrule, i, nonassoc_resolution);
229 flush_shift (s, i);
230 flush_reduce (lookaheads, i);
231 /* Record an explicit error for this token. */
232 errors[nerrs++] = symbols[i];
233 break;
234
235 case undef_assoc:
236 abort ();
237 }
238 }
239
240 /* Some tokens have been explicitly made errors. Allocate a
241 permanent errs structure for this state, to record them. */
242 state_errs_set (s, nerrs, errors);
243
244 if (obstack_object_size (&solved_conflicts_obstack))
245 {
246 obstack_1grow (&solved_conflicts_obstack, '\0');
247 s->solved_conflicts = obstack_finish (&solved_conflicts_obstack);
248 }
249 }
250
251
252 /*-------------------------------------------------------------------.
253 | Solve the S/R conflicts of state S using the |
254 | precedence/associativity, and flag it inconsistent if it still has |
255 | conflicts. ERRORS can be used as storage to compute the list of |
256 | lookaheads on which S raises a syntax error (%nonassoc). |
257 `-------------------------------------------------------------------*/
258
259 static void
260 set_conflicts (state *s, symbol **errors)
261 {
262 int i;
263 transitions *trans = s->transitions;
264 reductions *reds = s->reductions;
265
266 if (s->consistent)
267 return;
268
269 bitset_zero (lookaheadset);
270
271 FOR_EACH_SHIFT (trans, i)
272 bitset_set (lookaheadset, TRANSITION_SYMBOL (trans, i));
273
274 /* Loop over all rules which require lookahead in this state. First
275 check for shift-reduce conflict, and try to resolve using
276 precedence. */
277 for (i = 0; i < reds->num; ++i)
278 if (reds->rules[i]->prec && reds->rules[i]->prec->prec
279 && !bitset_disjoint_p (reds->lookaheads[i], lookaheadset))
280 {
281 resolve_sr_conflict (s, i, errors);
282 break;
283 }
284
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)
288 {
289 if (!bitset_disjoint_p (reds->lookaheads[i], lookaheadset))
290 conflicts[s->number] = 1;
291
292 bitset_or (lookaheadset, lookaheadset, reds->lookaheads[i]);
293 }
294 }
295
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
302 void
303 conflicts_solve (void)
304 {
305 state_number i;
306 /* List of lookaheads on which we explicitly raise a syntax error. */
307 symbol **errors = MALLOC (errors, ntokens + 1);
308
309 CALLOC (conflicts, nstates);
310 shiftset = bitset_create (ntokens, BITSET_FIXED);
311 lookaheadset = bitset_create (ntokens, BITSET_FIXED);
312 obstack_init (&solved_conflicts_obstack);
313
314 for (i = 0; i < nstates; i++)
315 {
316 set_conflicts (states[i], errors);
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
324 free (errors);
325 }
326
327
328 /*---------------------------------------------.
329 | Count the number of shift/reduce conflicts. |
330 `---------------------------------------------*/
331
332 static int
333 count_sr_conflicts (state *s)
334 {
335 int i;
336 int src_count = 0;
337 transitions *trans = s->transitions;
338 reductions *reds = s->reductions;
339
340 if (!trans)
341 return 0;
342
343 bitset_zero (lookaheadset);
344 bitset_zero (shiftset);
345
346 FOR_EACH_SHIFT (trans, i)
347 bitset_set (shiftset, TRANSITION_SYMBOL (trans, i));
348
349 for (i = 0; i < reds->num; ++i)
350 bitset_or (lookaheadset, lookaheadset, reds->lookaheads[i]);
351
352 bitset_and (lookaheadset, lookaheadset, shiftset);
353
354 src_count = bitset_count (lookaheadset);
355
356 return src_count;
357 }
358
359
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 +`----------------------------------------------------------------*/
366
367 static int
368 count_rr_conflicts (state *s, int one_per_token)
369 {
370 int i;
371 reductions *reds = s->reductions;
372 int rrc_count = 0;
373
374 for (i = 0; i < ntokens; i++)
375 {
376 int count = 0;
377 int j;
378 for (j = 0; j < reds->num; ++j)
379 if (bitset_test (reds->lookaheads[j], i))
380 count++;
381
382 if (count >= 2)
383 rrc_count += one_per_token ? 1 : count-1;
384 }
385
386 return rrc_count;
387 }
388
389
390 /*--------------------------------------------------------------.
391 | Return a human readable string which reports shift/reduce and |
392 | reduce/reduce conflict numbers (SRC_NUM, RRC_NUM). |
393 `--------------------------------------------------------------*/
394
395 static const char *
396 conflict_report (int src_num, int rrc_num)
397 {
398 static char res[4096];
399 char *cp = res;
400
401 if (src_num >= 1)
402 {
403 sprintf (cp, ngettext ("%d shift/reduce conflict",
404 "%d shift/reduce conflicts", src_num), src_num);
405 cp += strlen (cp);
406 }
407
408 if (src_num > 0 && rrc_num > 0)
409 {
410 sprintf (cp, " %s ", _("and"));
411 cp += strlen (cp);
412 }
413
414 if (rrc_num >= 1)
415 {
416 sprintf (cp, ngettext ("%d reduce/reduce conflict",
417 "%d reduce/reduce conflicts", rrc_num), rrc_num);
418 cp += strlen (cp);
419 }
420
421 *cp++ = '\0';
422
423 return res;
424 }
425
426
427 /*----------------------------------------------------------------.
428 | Same as above, but report the number of conflicts a` la POSIX. |
429 `----------------------------------------------------------------*/
430
431 static void
432 conflict_report_yacc (int src_num, int rrc_num)
433 {
434 /* If invoked with `--yacc', use the output format specified by
435 POSIX. */
436 fprintf (stderr, _("conflicts: "));
437 if (src_num > 0)
438 fprintf (stderr, _(" %d shift/reduce"), src_num);
439 if (src_num > 0 && rrc_num > 0)
440 fprintf (stderr, ",");
441 if (rrc_num > 0)
442 fprintf (stderr, _(" %d reduce/reduce"), rrc_num);
443 putc ('\n', stderr);
444 }
445
446
447 /*-----------------------------------------------------------.
448 | Output the detailed description of states with conflicts. |
449 `-----------------------------------------------------------*/
450
451 void
452 conflicts_output (FILE *out)
453 {
454 bool printed_sth = false;
455 state_number i;
456 for (i = 0; i < nstates; i++)
457 {
458 state *s = states[i];
459 if (conflicts[i])
460 {
461 fprintf (out, _("State %d contains "), i);
462 fprintf (out, "%s.\n",
463 conflict_report (count_sr_conflicts (s),
464 count_rr_conflicts (s, true)));
465 printed_sth = true;
466 }
467 }
468 if (printed_sth)
469 fputs ("\n\n", out);
470 }
471
472 /*--------------------------------------------------------.
473 | Total the number of S/R and R/R conflicts. Unlike the |
474 | code in conflicts_output, however, count EACH pair of |
475 | reductions for the same state and lookahead as one |
476 | conflict. |
477 `--------------------------------------------------------*/
478
479 int
480 conflicts_total_count (void)
481 {
482 state_number i;
483 int count;
484
485 /* Conflicts by state. */
486 count = 0;
487 for (i = 0; i < nstates; i++)
488 if (conflicts[i])
489 {
490 count += count_sr_conflicts (states[i]);
491 count += count_rr_conflicts (states[i], false);
492 }
493 return count;
494 }
495
496
497 /*------------------------------------------.
498 | Reporting the total number of conflicts. |
499 `------------------------------------------*/
500
501 void
502 conflicts_print (void)
503 {
504 /* Is the number of SR conflicts OK? Either EXPECTED_CONFLICTS is
505 not set, and then we want 0 SR, or else it is specified, in which
506 case we want equality. */
507 int src_ok = 0;
508
509 int src_total = 0;
510 int rrc_total = 0;
511
512 /* Conflicts by state. */
513 {
514 state_number i;
515
516 for (i = 0; i < nstates; i++)
517 if (conflicts[i])
518 {
519 src_total += count_sr_conflicts (states[i]);
520 rrc_total += count_rr_conflicts (states[i], true);
521 }
522 }
523
524 src_ok = src_total == (expected_conflicts == -1 ? 0 : expected_conflicts);
525
526 /* If there are no RR conflicts, and as many SR conflicts as
527 expected, then there is nothing to report. */
528 if (!rrc_total && src_ok)
529 return;
530
531 /* Report the total number of conflicts on STDERR. */
532 if (yacc_flag)
533 conflict_report_yacc (src_total, rrc_total);
534 else
535 warn ("%s", conflict_report (src_total, rrc_total));
536
537 if (expected_conflicts != -1 && !src_ok)
538 complain (ngettext ("expected %d shift/reduce conflict",
539 "expected %d shift/reduce conflicts",
540 expected_conflicts),
541 expected_conflicts);
542 }
543
544
545 void
546 conflicts_free (void)
547 {
548 XFREE (conflicts);
549 bitset_free (shiftset);
550 bitset_free (lookaheadset);
551 obstack_free (&solved_conflicts_obstack, NULL);
552 }