]> git.saurik.com Git - bison.git/blob - src/conflicts.c
* src/output.c (action_row, save_column, default_goto)
[bison.git] / src / conflicts.c
1 /* Find and resolve or report look-ahead conflicts for bison,
2 Copyright 1984, 1989, 1992, 2000, 2001 Free Software Foundation, Inc.
3
4 This file is part of Bison, the GNU Compiler Compiler.
5
6 Bison is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 Bison is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Bison; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
20
21 #include "system.h"
22 #include "complain.h"
23 #include "getargs.h"
24 #include "files.h"
25 #include "gram.h"
26 #include "state.h"
27 #include "lalr.h"
28 #include "conflicts.h"
29 #include "reader.h"
30 #include "LR0.h"
31
32 /* -1 stands for not specified. */
33 int expected_conflicts = -1;
34 static char *conflicts = NULL;
35
36 static unsigned *shiftset = NULL;
37 static unsigned *lookaheadset = NULL;
38 \f
39
40 static inline void
41 log_resolution (int state, int LAno, int token, char *resolution)
42 {
43 if (verbose_flag)
44 obstack_fgrow4 (&output_obstack,
45 _("\
46 Conflict in state %d between rule %d and token %s resolved as %s.\n"),
47 state, LAruleno[LAno], tags[token], resolution);
48 }
49
50
51 /*------------------------------------------------------------------.
52 | Turn off the shift recorded for the specified token in the |
53 | specified state. Used when we resolve a shift-reduce conflict in |
54 | favor of the reduction. |
55 `------------------------------------------------------------------*/
56
57 static void
58 flush_shift (int state, int token)
59 {
60 shifts *shiftp = state_table[state]->shifts;
61 int i;
62
63 for (i = 0; i < shiftp->nshifts; i++)
64 if (!SHIFT_IS_DISABLED (shiftp, i) && SHIFT_SYMBOL (shiftp, i) == token)
65 SHIFT_DISABLE (shiftp, i);
66 }
67
68
69 /*------------------------------------------------------------------.
70 | Attempt to resolve shift-reduce conflict for one rule by means of |
71 | precedence declarations. It has already been checked that the |
72 | rule has a precedence. A conflict is resolved by modifying the |
73 | shift or reduce tables so that there is no longer a conflict. |
74 `------------------------------------------------------------------*/
75
76 static void
77 resolve_sr_conflict (int state, int lookaheadnum)
78 {
79 int i;
80 /* find the rule to reduce by to get precedence of reduction */
81 int redprec = rule_table[LAruleno[lookaheadnum]].prec;
82 errs *errp = ERRS_ALLOC (ntokens + 1);
83 short *errtokens = errp->errs;
84
85 for (i = 0; i < ntokens; i++)
86 if (BITISSET (LA (lookaheadnum), i)
87 && BITISSET (lookaheadset, i)
88 && sprec[i])
89 /* Shift-reduce conflict occurs for token number i
90 and it has a precedence.
91 The precedence of shifting is that of token i. */
92 {
93 if (sprec[i] < redprec)
94 {
95 log_resolution (state, lookaheadnum, i, _("reduce"));
96 /* flush the shift for this token */
97 RESETBIT (lookaheadset, i);
98 flush_shift (state, i);
99 }
100 else if (sprec[i] > redprec)
101 {
102 log_resolution (state, lookaheadnum, i, _("shift"));
103 /* flush the reduce for this token */
104 RESETBIT (LA (lookaheadnum), i);
105 }
106 else
107 {
108 /* Matching precedence levels.
109 For left association, keep only the reduction.
110 For right association, keep only the shift.
111 For nonassociation, keep neither. */
112
113 switch (sassoc[i])
114 {
115 case right_assoc:
116 log_resolution (state, lookaheadnum, i, _("shift"));
117 break;
118
119 case left_assoc:
120 log_resolution (state, lookaheadnum, i, _("reduce"));
121 break;
122
123 case non_assoc:
124 log_resolution (state, lookaheadnum, i, _("an error"));
125 break;
126 }
127
128 if (sassoc[i] != right_assoc)
129 {
130 /* flush the shift for this token */
131 RESETBIT (lookaheadset, i);
132 flush_shift (state, i);
133 }
134 if (sassoc[i] != left_assoc)
135 {
136 /* flush the reduce for this token */
137 RESETBIT (LA (lookaheadnum), i);
138 }
139 if (sassoc[i] == non_assoc)
140 {
141 /* Record an explicit error for this token. */
142 *errtokens++ = i;
143 }
144 }
145 }
146
147 errp->nerrs = errtokens - errp->errs;
148 /* Some tokens have been explicitly made errors. Allocate a
149 permanent errs structure for this state, to record them. */
150 i = (char *) errtokens - (char *) errp;
151 state_table[state]->errs = ERRS_ALLOC (i + 1);
152 memcpy (state_table[state]->errs, errp, i);
153 free (errp);
154 }
155
156
157 static void
158 set_conflicts (int state)
159 {
160 int i, j;
161 shifts *shiftp;
162
163 if (state_table[state]->consistent)
164 return;
165
166 for (i = 0; i < tokensetsize; i++)
167 lookaheadset[i] = 0;
168
169 shiftp = state_table[state]->shifts;
170 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
171 if (!SHIFT_IS_DISABLED (shiftp, i))
172 SETBIT (lookaheadset, SHIFT_SYMBOL (shiftp, i));
173
174 /* Loop over all rules which require lookahead in this state. First
175 check for shift-reduce conflict, and try to resolve using
176 precedence */
177 for (i = state_table[state]->lookaheads;
178 i < state_table[state + 1]->lookaheads;
179 ++i)
180 if (rule_table[LAruleno[i]].prec)
181 for (j = 0; j < tokensetsize; ++j)
182 if (LA (i)[j] & lookaheadset[j])
183 {
184 resolve_sr_conflict (state, i);
185 break;
186 }
187
188
189 /* Loop over all rules which require lookahead in this state. Check
190 for conflicts not resolved above. */
191 for (i = state_table[state]->lookaheads;
192 i < state_table[state + 1]->lookaheads;
193 ++i)
194 {
195 for (j = 0; j < tokensetsize; ++j)
196 if (LA (i)[j] & lookaheadset[j])
197 conflicts[state] = 1;
198
199 for (j = 0; j < tokensetsize; ++j)
200 lookaheadset[j] |= LA (i)[j];
201 }
202 }
203
204 void
205 solve_conflicts (void)
206 {
207 int i;
208
209 conflicts = XCALLOC (char, nstates);
210 shiftset = XCALLOC (unsigned, tokensetsize);
211 lookaheadset = XCALLOC (unsigned, tokensetsize);
212
213 for (i = 0; i < nstates; i++)
214 set_conflicts (i);
215 }
216
217
218 /*---------------------------------------------.
219 | Count the number of shift/reduce conflicts. |
220 `---------------------------------------------*/
221
222 static int
223 count_sr_conflicts (int state)
224 {
225 int i, k;
226 int src_count = 0;
227 shifts *shiftp = state_table[state]->shifts;
228
229 if (!shiftp)
230 return 0;
231
232 for (i = 0; i < tokensetsize; i++)
233 {
234 shiftset[i] = 0;
235 lookaheadset[i] = 0;
236 }
237
238 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
239 if (!SHIFT_IS_DISABLED (shiftp, i))
240 SETBIT (shiftset, SHIFT_SYMBOL (shiftp, i));
241
242 for (i = state_table[state]->lookaheads;
243 i < state_table[state + 1]->lookaheads;
244 ++i)
245 for (k = 0; k < tokensetsize; ++k)
246 lookaheadset[k] |= LA (i)[k];
247
248 for (k = 0; k < tokensetsize; ++k)
249 lookaheadset[k] &= shiftset[k];
250
251 for (i = 0; i < ntokens; i++)
252 if (BITISSET (lookaheadset, i))
253 src_count++;
254
255 return src_count;
256 }
257
258
259 /*----------------------------------------------.
260 | Count the number of reduce/reduce conflicts. |
261 `----------------------------------------------*/
262
263 static int
264 count_rr_conflicts (int state)
265 {
266 int i;
267 int rrc_count = 0;
268
269 int m = state_table[state]->lookaheads;
270 int n = state_table[state + 1]->lookaheads;
271
272 if (n - m < 2)
273 return 0;
274
275 for (i = 0; i < ntokens; i++)
276 {
277 int count = 0;
278 int j;
279 for (j = m; j < n; j++)
280 if (BITISSET (LA (m), j))
281 count++;
282
283 if (count >= 2)
284 rrc_count++;
285 }
286
287 return rrc_count;
288 }
289
290 /*--------------------------------------------------------------.
291 | Return a human readable string which reports shift/reduce and |
292 | reduce/reduce conflict numbers (SRC_NUM, RRC_NUM). |
293 `--------------------------------------------------------------*/
294
295 static const char *
296 conflict_report (int src_num, int rrc_num)
297 {
298 static char res[4096];
299 char *cp = res;
300
301 if (src_num >= 1)
302 {
303 sprintf (cp, ngettext ("%d shift/reduce conflict",
304 "%d shift/reduce conflicts", src_num), src_num);
305 cp += strlen (cp);
306 }
307
308 if (src_num > 0 && rrc_num > 0)
309 {
310 sprintf (cp, " %s ", _("and"));
311 cp += strlen (cp);
312 }
313
314 if (rrc_num >= 1)
315 {
316 sprintf (cp, ngettext ("%d reduce/reduce conflict",
317 "%d reduce/reduce conflicts", rrc_num), rrc_num);
318 cp += strlen (cp);
319 }
320
321 *cp++ = '.';
322 *cp++ = '\n';
323 *cp++ = '\0';
324
325 return res;
326 }
327
328
329 /*-----------------------------------------------------------.
330 | Output the detailed description of states with conflicts. |
331 `-----------------------------------------------------------*/
332
333 void
334 conflicts_output (FILE *out)
335 {
336 bool printed_sth = FALSE;
337 int i;
338 for (i = 0; i < nstates; i++)
339 if (conflicts[i])
340 {
341 fprintf (out, _("State %d contains "), i);
342 fputs (conflict_report (count_sr_conflicts (i),
343 count_rr_conflicts (i)), out);
344 printed_sth = TRUE;
345 }
346 if (printed_sth)
347 fputs ("\n\n", out);
348 }
349
350
351 /*------------------------------------------.
352 | Reporting the total number of conflicts. |
353 `------------------------------------------*/
354
355 void
356 conflicts_print (void)
357 {
358 int i;
359
360 /* Is the number of SR conflicts OK? Either EXPECTED_CONFLICTS is
361 not set, and then we want 0 SR, or else it is specified, in which
362 case we want equality. */
363 int src_ok = 0;
364
365 int src_total = 0;
366 int rrc_total = 0;
367
368 /* Conflicts by state. */
369 for (i = 0; i < nstates; i++)
370 if (conflicts[i])
371 {
372 src_total += count_sr_conflicts (i);
373 rrc_total += count_rr_conflicts (i);
374 }
375
376 src_ok = src_total == (expected_conflicts == -1 ? 0 : expected_conflicts);
377
378 /* If there are no RR conflicts, and as many SR conflicts as
379 expected, then there is nothing to report. */
380 if (!rrc_total && src_ok)
381 return;
382
383 /* Report the total number of conflicts on STDERR. */
384 if (yacc_flag)
385 {
386 /* If invoked with `--yacc', use the output format specified by
387 POSIX. */
388 fprintf (stderr, _("conflicts: "));
389 if (src_total > 0)
390 fprintf (stderr, _(" %d shift/reduce"), src_total);
391 if (src_total > 0 && rrc_total > 0)
392 fprintf (stderr, ",");
393 if (rrc_total > 0)
394 fprintf (stderr, _(" %d reduce/reduce"), rrc_total);
395 putc ('\n', stderr);
396 }
397 else
398 {
399 fprintf (stderr, _("%s contains "), infile);
400 fputs (conflict_report (src_total, rrc_total), stderr);
401 }
402
403 if (expected_conflicts != -1 && !src_ok)
404 {
405 complain_message_count++;
406 fprintf (stderr, ngettext ("expected %d shift/reduce conflict\n",
407 "expected %d shift/reduce conflicts\n",
408 expected_conflicts),
409 expected_conflicts);
410 }
411 }
412
413
414 void
415 print_reductions (FILE *out, int state)
416 {
417 int i;
418 int j;
419 int m;
420 int n;
421 shifts *shiftp;
422 errs *errp;
423 int nodefault = 0;
424
425 for (i = 0; i < tokensetsize; i++)
426 shiftset[i] = 0;
427
428 shiftp = state_table[state]->shifts;
429 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
430 if (!SHIFT_IS_DISABLED (shiftp, i))
431 {
432 /* if this state has a shift for the error token, don't use a
433 default rule. */
434 if (SHIFT_IS_ERROR (shiftp, i))
435 nodefault = 1;
436 SETBIT (shiftset, SHIFT_SYMBOL (shiftp, i));
437 }
438
439 errp = state_table[state]->errs;
440 if (errp)
441 for (i = 0; i < errp->nerrs; i++)
442 if (errp->errs[i])
443 SETBIT (shiftset, errp->errs[i]);
444
445 m = state_table[state]->lookaheads;
446 n = state_table[state + 1]->lookaheads;
447
448 if (n - m == 1 && !nodefault)
449 {
450 int k;
451 int default_rule = LAruleno[m];
452
453 for (k = 0; k < tokensetsize; ++k)
454 lookaheadset[k] = LA (m)[k] & shiftset[k];
455
456 for (i = 0; i < ntokens; i++)
457 if (BITISSET (lookaheadset, i))
458 fprintf (out, _(" %-4s\t[reduce using rule %d (%s)]\n"),
459 tags[i], default_rule,
460 tags[rule_table[default_rule].lhs]);
461
462 fprintf (out, _(" $default\treduce using rule %d (%s)\n\n"),
463 default_rule, tags[rule_table[default_rule].lhs]);
464 }
465 else if (n - m >= 1)
466 {
467 int k;
468
469 int cmax = 0;
470 int default_LA = -1;
471 int default_rule = 0;
472
473 if (!nodefault)
474 for (i = m; i < n; i++)
475 {
476 int count = 0;
477
478 for (k = 0; k < tokensetsize; ++k)
479 lookaheadset[k] = LA (i)[k] & ~shiftset[k];
480
481 for (j = 0; j < ntokens; j++)
482 if (BITISSET (lookaheadset, j))
483 count++;
484
485 if (count > cmax)
486 {
487 cmax = count;
488 default_LA = i;
489 default_rule = LAruleno[i];
490 }
491
492 for (k = 0; k < tokensetsize; ++k)
493 shiftset[k] |= lookaheadset[k];
494 }
495
496 for (i = 0; i < tokensetsize; i++)
497 shiftset[i] = 0;
498
499 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
500 if (!SHIFT_IS_DISABLED (shiftp, i))
501 SETBIT (shiftset, SHIFT_SYMBOL (shiftp, i));
502
503 for (i = 0; i < ntokens; i++)
504 {
505 int defaulted = 0;
506 int count = BITISSET (shiftset, i);
507
508 for (j = m; j < n; j++)
509 {
510 if (BITISSET (LA (m), j))
511 {
512 if (count == 0)
513 {
514 if (j != default_LA)
515 fprintf (out,
516 _(" %-4s\treduce using rule %d (%s)\n"),
517 tags[i],
518 LAruleno[j],
519 tags[rule_table[LAruleno[j]].lhs]);
520 else
521 defaulted = 1;
522
523 count++;
524 }
525 else
526 {
527 if (defaulted)
528 fprintf (out,
529 _(" %-4s\treduce using rule %d (%s)\n"),
530 tags[i],
531 LAruleno[default_LA],
532 tags[rule_table[LAruleno[default_LA]].lhs]);
533 defaulted = 0;
534 fprintf (out,
535 _(" %-4s\t[reduce using rule %d (%s)]\n"),
536 tags[i],
537 LAruleno[j],
538 tags[rule_table[LAruleno[j]].lhs]);
539 }
540 }
541 }
542 }
543
544 if (default_LA >= 0)
545 fprintf (out, _(" $default\treduce using rule %d (%s)\n"),
546 default_rule, tags[rule_table[default_rule].lhs]);
547 }
548 }
549
550
551 void
552 free_conflicts (void)
553 {
554 XFREE (conflicts);
555 XFREE (shiftset);
556 XFREE (lookaheadset);
557 }