1 /* Find and resolve or report look-ahead conflicts for bison, 
   2    Copyright (C) 1984, 1989, 1992, 2000, 2001, 2002 
   3    Free Software Foundation, Inc. 
   5    This file is part of Bison, the GNU Compiler Compiler. 
   7    Bison is free software; you can redistribute it and/or modify it 
   8    under the terms of the GNU General Public License as published by 
   9    the Free Software Foundation; either version 2, or (at your option) 
  12    Bison is distributed in the hope that it will be useful, but 
  13    WITHOUT ANY WARRANTY; without even the implied warranty of 
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  15    General Public License for more details. 
  17    You should have received a copy of the GNU General Public License 
  18    along with Bison; see the file COPYING.  If not, write to the Free 
  19    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 
  31 #include "conflicts.h" 
  35 /* -1 stands for not specified. */ 
  36 int expected_conflicts 
= -1; 
  37 static char *conflicts 
= NULL
; 
  38 struct obstack solved_conflicts_obstack
; 
  40 static bitset shiftset
; 
  41 static bitset lookaheadset
; 
  45 enum conflict_resolution_e
 
  55 /*----------------------------------------------------------------. 
  56 | Explain how an SR conflict between TOKEN and RULE was resolved: | 
  58 `----------------------------------------------------------------*/ 
  61 log_resolution (rule_t 
*rule
, symbol_number_t token
, 
  62                 enum conflict_resolution_e resolution
) 
  64   if (report_flag 
& report_solved_conflicts
) 
  66       /* The description of the resolution. */ 
  69         case shift_resolution
: 
  70         case right_resolution
: 
  71           obstack_fgrow2 (&solved_conflicts_obstack
, 
  73     Conflict between rule %d and token %s resolved as shift"), 
  77         case reduce_resolution
: 
  79           obstack_fgrow2 (&solved_conflicts_obstack
, 
  81     Conflict between rule %d and token %s resolved as reduce"), 
  85         case nonassoc_resolution
: 
  86           obstack_fgrow2 (&solved_conflicts_obstack
, 
  88     Conflict between rule %d and token %s resolved as an error"), 
  97         case shift_resolution
: 
  98           obstack_fgrow2 (&solved_conflicts_obstack
, 
 101                           symbols
[token
]->tag
); 
 104         case reduce_resolution
: 
 105           obstack_fgrow2 (&solved_conflicts_obstack
, 
 111         case left_resolution
: 
 112           obstack_fgrow1 (&solved_conflicts_obstack
, 
 114                           symbols
[token
]->tag
); 
 117         case right_resolution
: 
 118           obstack_fgrow1 (&solved_conflicts_obstack
, 
 120                           symbols
[token
]->tag
); 
 122         case nonassoc_resolution
: 
 123           obstack_fgrow1 (&solved_conflicts_obstack
, 
 125                           symbols
[token
]->tag
); 
 128       obstack_sgrow (&solved_conflicts_obstack
, ".\n"); 
 133 /*------------------------------------------------------------------. 
 134 | Turn off the shift recorded for the specified token in the        | 
 135 | specified state.  Used when we resolve a shift-reduce conflict in | 
 136 | favor of the reduction.                                           | 
 137 `------------------------------------------------------------------*/ 
 140 flush_shift (state_t 
*state
, int token
) 
 142   transitions_t 
*transitions 
= state
->transitions
; 
 145   bitset_reset (lookaheadset
, token
); 
 146   for (i 
= 0; i 
< transitions
->num
; i
++) 
 147     if (!TRANSITION_IS_DISABLED (transitions
, i
) 
 148         && TRANSITION_SYMBOL (transitions
, i
) == token
) 
 149       TRANSITION_DISABLE (transitions
, i
); 
 153 /*-------------------------------------------------------------------. 
 154 | Turn off the reduce recorded for the specified token for the       | 
 155 | specified lookahead.  Used when we resolve a shift-reduce conflict | 
 156 | in favor of the shift.                                             | 
 157 `-------------------------------------------------------------------*/ 
 160 flush_reduce (bitset lookaheads
, int token
) 
 162   bitset_reset (lookaheads
, token
); 
 166 /*------------------------------------------------------------------. 
 167 | Attempt to resolve shift-reduce conflict for one rule by means of | 
 168 | precedence declarations.  It has already been checked that the    | 
 169 | rule has a precedence.  A conflict is resolved by modifying the   | 
 170 | shift or reduce tables so that there is no longer a conflict.     | 
 172 | LOOKAHEAD is the number of the lookahead bitset to consider.      | 
 174 | ERRS can be used to store discovered explicit errors.             | 
 175 `------------------------------------------------------------------*/ 
 178 resolve_sr_conflict (state_t 
*state
, int ruleno
, 
 182   reductions_t 
*reds 
= state
->reductions
; 
 183   /* Find the rule to reduce by to get precedence of reduction.  */ 
 184   rule_t 
*redrule 
= reds
->rules
[ruleno
]; 
 185   int redprec 
= redrule
->prec
->prec
; 
 186   bitset lookaheads 
= reds
->lookaheads
[ruleno
]; 
 189   for (i 
= 0; i 
< ntokens
; i
++) 
 190     if (bitset_test (lookaheads
, i
) 
 191         && bitset_test (lookaheadset
, i
) 
 194         /* Shift-reduce conflict occurs for token number i 
 195            and it has a precedence. 
 196            The precedence of shifting is that of token i.  */ 
 197         if (symbols
[i
]->prec 
< redprec
) 
 199             log_resolution (redrule
, i
, reduce_resolution
); 
 200             flush_shift (state
, i
); 
 202         else if (symbols
[i
]->prec 
> redprec
) 
 204             log_resolution (redrule
, i
, shift_resolution
); 
 205             flush_reduce (lookaheads
, i
); 
 208           /* Matching precedence levels. 
 209              For left association, keep only the reduction. 
 210              For right association, keep only the shift. 
 211              For nonassociation, keep neither.  */ 
 213           switch (symbols
[i
]->assoc
) 
 216               log_resolution (redrule
, i
, right_resolution
); 
 217               flush_reduce (lookaheads
, i
); 
 221               log_resolution (redrule
, i
, left_resolution
); 
 222               flush_shift (state
, i
); 
 226               log_resolution (redrule
, i
, nonassoc_resolution
); 
 227               flush_shift (state
, i
); 
 228               flush_reduce (lookaheads
, i
); 
 229               /* Record an explicit error for this token.  */ 
 230               errs
[nerrs
++] = symbols
[i
]; 
 234               assert (symbols
[i
]->assoc 
!= undef_assoc
); 
 239   /* Some tokens have been explicitly made errors.  Allocate a 
 240      permanent errs structure for this state, to record them.  */ 
 241   state_errs_set (state
, nerrs
, errs
); 
 243   if (obstack_object_size (&solved_conflicts_obstack
)) 
 245       obstack_1grow (&solved_conflicts_obstack
, '\0'); 
 246       state
->solved_conflicts 
= obstack_finish (&solved_conflicts_obstack
); 
 251 /*-------------------------------------------------------------------. 
 252 | Solve the S/R conflicts of STATE using the                         | 
 253 | precedence/associativity, and flag it inconsistent if it still has | 
 254 | conflicts.  ERRS can be used as storage to compute the list of     | 
 255 | lookaheads on which this STATE raises a parse error (%nonassoc).   | 
 256 `-------------------------------------------------------------------*/ 
 259 set_conflicts (state_t 
*state
, symbol_t 
**errs
) 
 262   transitions_t 
*transitions 
= state
->transitions
; 
 263   reductions_t 
*reds 
= state
->reductions
; 
 265   if (state
->consistent
) 
 268   bitset_zero (lookaheadset
); 
 270   FOR_EACH_SHIFT (transitions
, i
) 
 271     bitset_set (lookaheadset
, TRANSITION_SYMBOL (transitions
, i
)); 
 273   /* Loop over all rules which require lookahead in this state.  First 
 274      check for shift-reduce conflict, and try to resolve using 
 276   for (i 
= 0; i 
< reds
->num
; ++i
) 
 277     if (reds
->rules
[i
]->prec 
&& reds
->rules
[i
]->prec
->prec
 
 278         && !bitset_disjoint_p (reds
->lookaheads
[i
], lookaheadset
)) 
 280         resolve_sr_conflict (state
, i
, errs
); 
 284   /* Loop over all rules which require lookahead in this state.  Check 
 285      for conflicts not resolved above.  */ 
 286   for (i 
= 0; i 
< reds
->num
; ++i
) 
 288       if (!bitset_disjoint_p (reds
->lookaheads
[i
], lookaheadset
)) 
 289         conflicts
[state
->number
] = 1; 
 291       bitset_or (lookaheadset
, lookaheadset
, reds
->lookaheads
[i
]); 
 296 /*----------------------------------------------------------------. 
 297 | Solve all the S/R conflicts using the precedence/associativity, | 
 298 | and flag as inconsistent the states that still have conflicts.  | 
 299 `----------------------------------------------------------------*/ 
 302 conflicts_solve (void) 
 305   /* List of lookaheads on which we explicitly raise a parse error.  */ 
 306   symbol_t 
**errs 
= XMALLOC (symbol_t 
*, ntokens 
+ 1); 
 308   conflicts 
= XCALLOC (char, nstates
); 
 309   shiftset 
= bitset_create (ntokens
, BITSET_FIXED
); 
 310   lookaheadset 
= bitset_create (ntokens
, BITSET_FIXED
); 
 311   obstack_init (&solved_conflicts_obstack
); 
 313   for (i 
= 0; i 
< nstates
; i
++) 
 315       set_conflicts (states
[i
], errs
); 
 317       /* For uniformity of the code, make sure all the states have a valid 
 319       if (!states
[i
]->errs
) 
 320         states
[i
]->errs 
= errs_new (0, 0); 
 327 /*---------------------------------------------. 
 328 | Count the number of shift/reduce conflicts.  | 
 329 `---------------------------------------------*/ 
 332 count_sr_conflicts (state_t 
*state
) 
 336   transitions_t 
*transitions 
= state
->transitions
; 
 337   reductions_t 
*reds 
= state
->reductions
; 
 342   bitset_zero (lookaheadset
); 
 343   bitset_zero (shiftset
); 
 345   FOR_EACH_SHIFT (transitions
, i
) 
 346     bitset_set (shiftset
, TRANSITION_SYMBOL (transitions
, i
)); 
 348   for (i 
= 0; i 
< reds
->num
; ++i
) 
 349     bitset_or (lookaheadset
, lookaheadset
, reds
->lookaheads
[i
]); 
 351   bitset_and (lookaheadset
, lookaheadset
, shiftset
); 
 353   src_count 
= bitset_count (lookaheadset
); 
 359 /*----------------------------------------------------------------. 
 360 | Count the number of reduce/reduce conflicts.  If ONE_PER_TOKEN, | 
 361 | count one conflict for each token that has any reduce/reduce    | 
 362 | conflicts.  Otherwise, count one conflict for each pair of      | 
 363 | conflicting reductions.                                         | 
 364 +`----------------------------------------------------------------*/ 
 367 count_rr_conflicts (state_t 
*state
, int one_per_token
) 
 370   reductions_t 
*reds 
= state
->reductions
; 
 373   for (i 
= 0; i 
< ntokens
; i
++) 
 377       for (j 
= 0; j 
< reds
->num
; ++j
) 
 378         if (bitset_test (reds
->lookaheads
[j
], i
)) 
 382         rrc_count 
+= one_per_token 
? 1 : count
-1; 
 389 /*--------------------------------------------------------------. 
 390 | Return a human readable string which reports shift/reduce and | 
 391 | reduce/reduce conflict numbers (SRC_NUM, RRC_NUM).            | 
 392 `--------------------------------------------------------------*/ 
 395 conflict_report (int src_num
, int rrc_num
) 
 397   static char res
[4096]; 
 402       sprintf (cp
, ngettext ("%d shift/reduce conflict", 
 403                              "%d shift/reduce conflicts", src_num
), src_num
); 
 407   if (src_num 
> 0 && rrc_num 
> 0) 
 409       sprintf (cp
, " %s ", _("and")); 
 415       sprintf (cp
, ngettext ("%d reduce/reduce conflict", 
 416                              "%d reduce/reduce conflicts", rrc_num
), rrc_num
); 
 426 /*----------------------------------------------------------------. 
 427 | Same as above, but report the number of conflicts a` la POSIX.  | 
 428 `----------------------------------------------------------------*/ 
 431 conflict_report_yacc (int src_num
, int rrc_num
) 
 433   /* If invoked with `--yacc', use the output format specified by 
 435   fprintf (stderr
, _("conflicts: ")); 
 437     fprintf (stderr
, _(" %d shift/reduce"), src_num
); 
 438   if (src_num 
> 0 && rrc_num 
> 0) 
 439     fprintf (stderr
, ","); 
 441     fprintf (stderr
, _(" %d reduce/reduce"), rrc_num
); 
 446 /*-----------------------------------------------------------. 
 447 | Output the detailed description of states with conflicts.  | 
 448 `-----------------------------------------------------------*/ 
 451 conflicts_output (FILE *out
) 
 453   bool printed_sth 
= false; 
 455   for (i 
= 0; i 
< nstates
; i
++) 
 457       state_t 
*s 
= states
[i
]; 
 460           fprintf (out
, _("State %d contains "), i
); 
 461           fprintf (out
, "%s.\n", 
 462                    conflict_report (count_sr_conflicts (s
), 
 463                                     count_rr_conflicts (s
, true))); 
 471 /*--------------------------------------------------------. 
 472 | Total the number of S/R and R/R conflicts.  Unlike the  | 
 473 | code in conflicts_output, however, count EACH pair of   | 
 474 | reductions for the same state and lookahead as one      | 
 476 `--------------------------------------------------------*/ 
 479 conflicts_total_count (void) 
 484   /* Conflicts by state.  */ 
 486   for (i 
= 0; i 
< nstates
; i
++) 
 489         count 
+= count_sr_conflicts (states
[i
]); 
 490         count 
+= count_rr_conflicts (states
[i
], false); 
 496 /*------------------------------------------. 
 497 | Reporting the total number of conflicts.  | 
 498 `------------------------------------------*/ 
 501 conflicts_print (void) 
 503   /* Is the number of SR conflicts OK?  Either EXPECTED_CONFLICTS is 
 504      not set, and then we want 0 SR, or else it is specified, in which 
 505      case we want equality.  */ 
 511   /* Conflicts by state.  */ 
 515     for (i 
= 0; i 
< nstates
; i
++) 
 518           src_total 
+= count_sr_conflicts (states
[i
]); 
 519           rrc_total 
+= count_rr_conflicts (states
[i
], true); 
 523   src_ok 
= src_total 
== (expected_conflicts 
== -1 ? 0 : expected_conflicts
); 
 525   /* If there are no RR conflicts, and as many SR conflicts as 
 526      expected, then there is nothing to report.  */ 
 527   if (!rrc_total 
&& src_ok
) 
 530   /* Report the total number of conflicts on STDERR.  */ 
 532     conflict_report_yacc (src_total
, rrc_total
); 
 534     warn ("%s", conflict_report (src_total
, rrc_total
)); 
 536   if (expected_conflicts 
!= -1 && !src_ok
) 
 537     complain (ngettext ("expected %d shift/reduce conflict", 
 538                         "expected %d shift/reduce conflicts", 
 545 conflicts_free (void) 
 548   bitset_free (shiftset
); 
 549   bitset_free (lookaheadset
); 
 550   obstack_free (&solved_conflicts_obstack
, NULL
);