]> git.saurik.com Git - bison.git/blame - src/conflicts.c
* src/output.c: Various formatting changes.
[bison.git] / src / conflicts.c
CommitLineData
08089d5d 1/* Find and resolve or report look-ahead conflicts for bison,
22c821f3 2 Copyright 1984, 1989, 1992, 2000, 2001 Free Software Foundation, Inc.
08089d5d 3
ceed8467 4 This file is part of Bison, the GNU Compiler Compiler.
08089d5d 5
ceed8467
AD
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.
08089d5d 10
ceed8467
AD
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.
08089d5d 15
ceed8467
AD
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. */
08089d5d 20
08089d5d 21#include "system.h"
7da99ede 22#include "complain.h"
ceed8467 23#include "getargs.h"
08089d5d
DM
24#include "files.h"
25#include "gram.h"
26#include "state.h"
720d742f 27#include "lalr.h"
0619caf0 28#include "conflicts.h"
b2ca4022
AD
29#include "reader.h"
30#include "LR0.h"
d2729d44 31
7da99ede
AD
32/* -1 stands for not specified. */
33int expected_conflicts = -1;
342b8b6e 34static char *conflicts = NULL;
08089d5d 35
342b8b6e
AD
36static unsigned *shiftset = NULL;
37static unsigned *lookaheadset = NULL;
c29240e7 38\f
08089d5d 39
c29240e7
AD
40static inline void
41log_resolution (int state, int LAno, int token, char *resolution)
08089d5d 42{
64d15509
AD
43 if (verbose_flag)
44 obstack_fgrow4 (&output_obstack,
45 _("\
c29240e7 46Conflict in state %d between rule %d and token %s resolved as %s.\n"),
64d15509 47 state, LAruleno[LAno], tags[token], resolution);
08089d5d
DM
48}
49
50
c29240e7
AD
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
4a120d45 57static void
c29240e7 58flush_shift (int state, int token)
08089d5d 59{
f693ad14 60 shifts *shiftp = state_table[state]->shifts;
9f136c07 61 int i;
c29240e7 62
d954473d
AD
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);
08089d5d
DM
66}
67
68
c29240e7
AD
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`------------------------------------------------------------------*/
08089d5d 75
4a120d45 76static void
d2729d44 77resolve_sr_conflict (int state, int lookaheadnum)
08089d5d 78{
c29240e7 79 int i;
9f136c07
AD
80 /* find the rule to reduce by to get precedence of reduction */
81 int redprec = rule_table[LAruleno[lookaheadnum]].prec;
f59c437a 82 errs *errp = ERRS_ALLOC (ntokens + 1);
08089d5d
DM
83 short *errtokens = errp->errs;
84
08089d5d 85 for (i = 0; i < ntokens; i++)
92b16366
AD
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
08089d5d 147 errp->nerrs = errtokens - errp->errs;
92b16366
AD
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;
f693ad14
AD
151 state_table[state]->errs = ERRS_ALLOC (i + 1);
152 memcpy (state_table[state]->errs, errp, i);
c29240e7 153 free (errp);
08089d5d
DM
154}
155
156
4a120d45 157static void
c29240e7 158set_conflicts (int state)
08089d5d 159{
d8cf039f 160 int i, j;
c29240e7 161 shifts *shiftp;
c29240e7 162
f693ad14 163 if (state_table[state]->consistent)
c29240e7 164 return;
08089d5d 165
c29240e7
AD
166 for (i = 0; i < tokensetsize; i++)
167 lookaheadset[i] = 0;
08089d5d 168
f693ad14 169 shiftp = state_table[state]->shifts;
d954473d
AD
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));
08089d5d 173
c29240e7
AD
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 */
f693ad14
AD
177 for (i = state_table[state]->lookaheads;
178 i < state_table[state + 1]->lookaheads;
d8cf039f 179 ++i)
652a871c 180 if (rule_table[LAruleno[i]].prec)
d8cf039f
AD
181 for (j = 0; j < tokensetsize; ++j)
182 if (LA (i)[j] & lookaheadset[j])
c29240e7 183 {
d8cf039f
AD
184 resolve_sr_conflict (state, i);
185 break;
c29240e7 186 }
08089d5d 187
08089d5d 188
c29240e7
AD
189 /* Loop over all rules which require lookahead in this state. Check
190 for conflicts not resolved above. */
f693ad14
AD
191 for (i = state_table[state]->lookaheads;
192 i < state_table[state + 1]->lookaheads;
d8cf039f 193 ++i)
08089d5d 194 {
d8cf039f
AD
195 for (j = 0; j < tokensetsize; ++j)
196 if (LA (i)[j] & lookaheadset[j])
0df87bb6 197 conflicts[state] = 1;
08089d5d 198
d8cf039f
AD
199 for (j = 0; j < tokensetsize; ++j)
200 lookaheadset[j] |= LA (i)[j];
c29240e7
AD
201 }
202}
08089d5d
DM
203
204void
342b8b6e 205solve_conflicts (void)
08089d5d 206{
c29240e7 207 int i;
08089d5d 208
d7913476
AD
209 conflicts = XCALLOC (char, nstates);
210 shiftset = XCALLOC (unsigned, tokensetsize);
211 lookaheadset = XCALLOC (unsigned, tokensetsize);
08089d5d 212
c29240e7
AD
213 for (i = 0; i < nstates; i++)
214 set_conflicts (i);
08089d5d
DM
215}
216
217
c29240e7
AD
218/*---------------------------------------------.
219| Count the number of shift/reduce conflicts. |
220`---------------------------------------------*/
221
0df87bb6 222static int
d2729d44 223count_sr_conflicts (int state)
08089d5d 224{
52afa962 225 int i, k;
0df87bb6 226 int src_count = 0;
f693ad14 227 shifts *shiftp = state_table[state]->shifts;
08089d5d 228
c29240e7 229 if (!shiftp)
0df87bb6 230 return 0;
08089d5d
DM
231
232 for (i = 0; i < tokensetsize; i++)
233 {
234 shiftset[i] = 0;
235 lookaheadset[i] = 0;
236 }
237
52afa962 238 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
9839bbe5
AD
239 if (!SHIFT_IS_DISABLED (shiftp, i))
240 SETBIT (shiftset, SHIFT_SYMBOL (shiftp, i));
08089d5d 241
f693ad14
AD
242 for (i = state_table[state]->lookaheads;
243 i < state_table[state + 1]->lookaheads;
52afa962
AD
244 ++i)
245 for (k = 0; k < tokensetsize; ++k)
246 lookaheadset[k] |= LA (i)[k];
08089d5d 247
52afa962
AD
248 for (k = 0; k < tokensetsize; ++k)
249 lookaheadset[k] &= shiftset[k];
08089d5d 250
08089d5d 251 for (i = 0; i < ntokens; i++)
52afa962
AD
252 if (BITISSET (lookaheadset, i))
253 src_count++;
0df87bb6
AD
254
255 return src_count;
08089d5d
DM
256}
257
258
c29240e7
AD
259/*----------------------------------------------.
260| Count the number of reduce/reduce conflicts. |
261`----------------------------------------------*/
262
0df87bb6 263static int
d2729d44 264count_rr_conflicts (int state)
08089d5d 265{
c29240e7 266 int i;
0df87bb6 267 int rrc_count = 0;
08089d5d 268
f693ad14
AD
269 int m = state_table[state]->lookaheads;
270 int n = state_table[state + 1]->lookaheads;
08089d5d 271
c29240e7 272 if (n - m < 2)
0df87bb6 273 return 0;
08089d5d 274
08089d5d
DM
275 for (i = 0; i < ntokens; i++)
276 {
0df87bb6
AD
277 int count = 0;
278 int j;
08089d5d 279 for (j = m; j < n; j++)
52afa962
AD
280 if (BITISSET (LA (m), j))
281 count++;
08089d5d 282
c29240e7
AD
283 if (count >= 2)
284 rrc_count++;
08089d5d 285 }
0df87bb6
AD
286
287 return rrc_count;
08089d5d
DM
288}
289
ff4423cc
AD
290/*--------------------------------------------------------------.
291| Return a human readable string which reports shift/reduce and |
292| reduce/reduce conflict numbers (SRC_NUM, RRC_NUM). |
293`--------------------------------------------------------------*/
c29240e7 294
ff4423cc
AD
295static const char *
296conflict_report (int src_num, int rrc_num)
c29240e7 297{
ff4423cc
AD
298 static char res[4096];
299 char *cp = res;
300
7da99ede 301 if (src_num >= 1)
22c821f3 302 {
7da99ede
AD
303 sprintf (cp, ngettext ("%d shift/reduce conflict",
304 "%d shift/reduce conflicts", src_num), src_num);
22c821f3
AD
305 cp += strlen (cp);
306 }
c29240e7 307
0619caf0 308 if (src_num > 0 && rrc_num > 0)
22c821f3 309 {
7da99ede 310 sprintf (cp, " %s ", _("and"));
22c821f3
AD
311 cp += strlen (cp);
312 }
c29240e7 313
7da99ede 314 if (rrc_num >= 1)
22c821f3 315 {
7da99ede
AD
316 sprintf (cp, ngettext ("%d reduce/reduce conflict",
317 "%d reduce/reduce conflicts", rrc_num), rrc_num);
22c821f3
AD
318 cp += strlen (cp);
319 }
ff4423cc
AD
320
321 *cp++ = '.';
322 *cp++ = '\n';
323 *cp++ = '\0';
c29240e7 324
ff4423cc 325 return res;
c29240e7
AD
326}
327
328
0df87bb6
AD
329/*-----------------------------------------------------------.
330| Output the detailed description of states with conflicts. |
331`-----------------------------------------------------------*/
c29240e7
AD
332
333void
0df87bb6 334conflicts_output (FILE *out)
c29240e7 335{
d2d1b42b 336 bool printed_sth = FALSE;
c29240e7 337 int i;
0df87bb6
AD
338 for (i = 0; i < nstates; i++)
339 if (conflicts[i])
340 {
7da99ede 341 fprintf (out, _("State %d contains "), i);
0df87bb6
AD
342 fputs (conflict_report (count_sr_conflicts (i),
343 count_rr_conflicts (i)), out);
d2d1b42b 344 printed_sth = TRUE;
0df87bb6 345 }
d2d1b42b
AD
346 if (printed_sth)
347 fputs ("\n\n", out);
0df87bb6 348}
c29240e7 349
c29240e7 350
0df87bb6
AD
351/*------------------------------------------.
352| Reporting the total number of conflicts. |
353`------------------------------------------*/
0619caf0 354
0df87bb6
AD
355void
356conflicts_print (void)
357{
358 int i;
359
a034c8b8
AD
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
0df87bb6
AD
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 }
c29240e7 375
a034c8b8
AD
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
0619caf0 383 /* Report the total number of conflicts on STDERR. */
a034c8b8 384 if (yacc_flag)
09b503c8 385 {
a034c8b8
AD
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);
09b503c8 401 }
7da99ede 402
a034c8b8 403 if (expected_conflicts != -1 && !src_ok)
7da99ede
AD
404 {
405 complain_message_count++;
81e895c0
AD
406 fprintf (stderr, ngettext ("expected %d shift/reduce conflict\n",
407 "expected %d shift/reduce conflicts\n",
7da99ede
AD
408 expected_conflicts),
409 expected_conflicts);
410 }
c29240e7
AD
411}
412
413
08089d5d 414void
c73a41af 415print_reductions (FILE *out, int state)
08089d5d 416{
c29240e7
AD
417 int i;
418 int j;
c29240e7
AD
419 int m;
420 int n;
c29240e7
AD
421 shifts *shiftp;
422 errs *errp;
08089d5d
DM
423 int nodefault = 0;
424
425 for (i = 0; i < tokensetsize; i++)
426 shiftset[i] = 0;
427
f693ad14 428 shiftp = state_table[state]->shifts;
d954473d
AD
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 }
08089d5d 438
f693ad14 439 errp = state_table[state]->errs;
08089d5d 440 if (errp)
e74dc321
AD
441 for (i = 0; i < errp->nerrs; i++)
442 if (errp->errs[i])
443 SETBIT (shiftset, errp->errs[i]);
08089d5d 444
f693ad14
AD
445 m = state_table[state]->lookaheads;
446 n = state_table[state + 1]->lookaheads;
08089d5d 447
c29240e7 448 if (n - m == 1 && !nodefault)
08089d5d 449 {
a04bc341 450 int k;
52afa962 451 int default_rule = LAruleno[m];
08089d5d 452
a04bc341
AD
453 for (k = 0; k < tokensetsize; ++k)
454 lookaheadset[k] = LA (m)[k] & shiftset[k];
08089d5d
DM
455
456 for (i = 0; i < ntokens; i++)
a04bc341
AD
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]);
08089d5d 461
c73a41af 462 fprintf (out, _(" $default\treduce using rule %d (%s)\n\n"),
b2ed6e58 463 default_rule, tags[rule_table[default_rule].lhs]);
08089d5d
DM
464 }
465 else if (n - m >= 1)
466 {
768fca83 467 int k;
c8ea038e 468
52afa962
AD
469 int cmax = 0;
470 int default_LA = -1;
471 int default_rule = 0;
08089d5d 472
c29240e7 473 if (!nodefault)
08089d5d
DM
474 for (i = m; i < n; i++)
475 {
e74dc321
AD
476 int count = 0;
477
768fca83
AD
478 for (k = 0; k < tokensetsize; ++k)
479 lookaheadset[k] = LA (i)[k] & ~shiftset[k];
ceed8467 480
08089d5d 481 for (j = 0; j < ntokens; j++)
768fca83
AD
482 if (BITISSET (lookaheadset, j))
483 count++;
ceed8467 484
08089d5d
DM
485 if (count > cmax)
486 {
487 cmax = count;
488 default_LA = i;
489 default_rule = LAruleno[i];
490 }
ceed8467 491
e74dc321
AD
492 for (k = 0; k < tokensetsize; ++k)
493 shiftset[k] |= lookaheadset[k];
08089d5d
DM
494 }
495
496 for (i = 0; i < tokensetsize; i++)
c29240e7 497 shiftset[i] = 0;
08089d5d 498
d954473d
AD
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));
08089d5d 502
08089d5d
DM
503 for (i = 0; i < ntokens; i++)
504 {
505 int defaulted = 0;
e74dc321 506 int count = BITISSET (shiftset, i);
08089d5d 507
08089d5d
DM
508 for (j = m; j < n; j++)
509 {
e74dc321 510 if (BITISSET (LA (m), j))
08089d5d
DM
511 {
512 if (count == 0)
513 {
514 if (j != default_LA)
a17e599f
AD
515 fprintf (out,
516 _(" %-4s\treduce using rule %d (%s)\n"),
517 tags[i],
518 LAruleno[j],
519 tags[rule_table[LAruleno[j]].lhs]);
c29240e7
AD
520 else
521 defaulted = 1;
08089d5d
DM
522
523 count++;
524 }
525 else
526 {
527 if (defaulted)
a17e599f
AD
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;
c73a41af 534 fprintf (out,
c29240e7 535 _(" %-4s\t[reduce using rule %d (%s)]\n"),
a17e599f
AD
536 tags[i],
537 LAruleno[j],
538 tags[rule_table[LAruleno[j]].lhs]);
08089d5d
DM
539 }
540 }
08089d5d
DM
541 }
542 }
543
544 if (default_LA >= 0)
c73a41af 545 fprintf (out, _(" $default\treduce using rule %d (%s)\n"),
b2ed6e58 546 default_rule, tags[rule_table[default_rule].lhs]);
08089d5d
DM
547 }
548}
549
550
551void
342b8b6e 552free_conflicts (void)
08089d5d 553{
d7913476
AD
554 XFREE (conflicts);
555 XFREE (shiftset);
556 XFREE (lookaheadset);
08089d5d 557}