1 /* Find and resolve or report look-ahead conflicts for bison, 
   3    Copyright (C) 1984, 1989, 1992, 2000, 2001, 2002, 2003, 2004, 2005, 2006 
   4    Free Software Foundation, Inc. 
   6    This file is part of Bison, the GNU Compiler Compiler. 
   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) 
  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. 
  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., 51 Franklin Street, Fifth Floor, Boston, MA 
  30 #include "conflicts.h" 
  39 /* -1 stands for not specified. */ 
  40 int expected_sr_conflicts 
= -1; 
  41 int expected_rr_conflicts 
= -1; 
  42 static char *conflicts
; 
  43 static struct obstack solved_conflicts_obstack
; 
  45 static bitset shift_set
; 
  46 static bitset look_ahead_set
; 
  50 enum conflict_resolution
 
  60 /*----------------------------------------------------------------. 
  61 | Explain how an SR conflict between TOKEN and RULE was resolved: | 
  63 `----------------------------------------------------------------*/ 
  66 log_resolution (rule 
*r
, symbol_number token
, 
  67                 enum conflict_resolution resolution
) 
  69   if (report_flag 
& report_solved_conflicts
) 
  71       /* The description of the resolution. */ 
  74         case shift_resolution
: 
  75         case right_resolution
: 
  76           obstack_fgrow2 (&solved_conflicts_obstack
, 
  78     Conflict between rule %d and token %s resolved as shift"), 
  82         case reduce_resolution
: 
  84           obstack_fgrow2 (&solved_conflicts_obstack
, 
  86     Conflict between rule %d and token %s resolved as reduce"), 
  90         case nonassoc_resolution
: 
  91           obstack_fgrow2 (&solved_conflicts_obstack
, 
  93     Conflict between rule %d and token %s resolved as an error"), 
 102         case shift_resolution
: 
 103           obstack_fgrow2 (&solved_conflicts_obstack
, 
 106                           symbols
[token
]->tag
); 
 109         case reduce_resolution
: 
 110           obstack_fgrow2 (&solved_conflicts_obstack
, 
 116         case left_resolution
: 
 117           obstack_fgrow1 (&solved_conflicts_obstack
, 
 119                           symbols
[token
]->tag
); 
 122         case right_resolution
: 
 123           obstack_fgrow1 (&solved_conflicts_obstack
, 
 125                           symbols
[token
]->tag
); 
 127         case nonassoc_resolution
: 
 128           obstack_fgrow1 (&solved_conflicts_obstack
, 
 130                           symbols
[token
]->tag
); 
 133       obstack_sgrow (&solved_conflicts_obstack
, ".\n"); 
 138 /*------------------------------------------------------------------. 
 139 | Turn off the shift recorded for the specified token in the        | 
 140 | specified state.  Used when we resolve a shift-reduce conflict in | 
 141 | favor of the reduction.                                           | 
 142 `------------------------------------------------------------------*/ 
 145 flush_shift (state 
*s
, int token
) 
 147   transitions 
*trans 
= s
->transitions
; 
 150   bitset_reset (look_ahead_set
, token
); 
 151   for (i 
= 0; i 
< trans
->num
; i
++) 
 152     if (!TRANSITION_IS_DISABLED (trans
, i
) 
 153         && TRANSITION_SYMBOL (trans
, i
) == token
) 
 154       TRANSITION_DISABLE (trans
, i
); 
 158 /*--------------------------------------------------------------------. 
 159 | Turn off the reduce recorded for the specified token for the        | 
 160 | specified look-ahead.  Used when we resolve a shift-reduce conflict | 
 161 | in favor of the shift.                                              | 
 162 `--------------------------------------------------------------------*/ 
 165 flush_reduce (bitset look_ahead_tokens
, int token
) 
 167   bitset_reset (look_ahead_tokens
, token
); 
 171 /*------------------------------------------------------------------. 
 172 | Attempt to resolve shift-reduce conflict for one rule by means of | 
 173 | precedence declarations.  It has already been checked that the    | 
 174 | rule has a precedence.  A conflict is resolved by modifying the   | 
 175 | shift or reduce tables so that there is no longer a conflict.     | 
 177 | RULENO is the number of the look-ahead bitset to consider.      | 
 179 | ERRORS can be used to store discovered explicit errors.           | 
 180 `------------------------------------------------------------------*/ 
 183 resolve_sr_conflict (state 
*s
, int ruleno
, symbol 
**errors
) 
 186   reductions 
*reds 
= s
->reductions
; 
 187   /* Find the rule to reduce by to get precedence of reduction.  */ 
 188   rule 
*redrule 
= reds
->rules
[ruleno
]; 
 189   int redprec 
= redrule
->prec
->prec
; 
 190   bitset look_ahead_tokens 
= reds
->look_ahead_tokens
[ruleno
]; 
 193   for (i 
= 0; i 
< ntokens
; i
++) 
 194     if (bitset_test (look_ahead_tokens
, i
) 
 195         && bitset_test (look_ahead_set
, i
) 
 198         /* Shift-reduce conflict occurs for token number i 
 199            and it has a precedence. 
 200            The precedence of shifting is that of token i.  */ 
 201         if (symbols
[i
]->prec 
< redprec
) 
 203             log_resolution (redrule
, i
, reduce_resolution
); 
 206         else if (symbols
[i
]->prec 
> redprec
) 
 208             log_resolution (redrule
, i
, shift_resolution
); 
 209             flush_reduce (look_ahead_tokens
, i
); 
 212           /* Matching precedence levels. 
 213              For left association, keep only the reduction. 
 214              For right association, keep only the shift. 
 215              For nonassociation, keep neither.  */ 
 217           switch (symbols
[i
]->assoc
) 
 223               log_resolution (redrule
, i
, right_resolution
); 
 224               flush_reduce (look_ahead_tokens
, i
); 
 228               log_resolution (redrule
, i
, left_resolution
); 
 233               log_resolution (redrule
, i
, nonassoc_resolution
); 
 235               flush_reduce (look_ahead_tokens
, i
); 
 236               /* Record an explicit error for this token.  */ 
 237               errors
[nerrs
++] = symbols
[i
]; 
 244       /* Some tokens have been explicitly made errors.  Allocate a 
 245          permanent errs structure for this state, to record them.  */ 
 246       state_errs_set (s
, nerrs
, errors
); 
 249   if (obstack_object_size (&solved_conflicts_obstack
)) 
 251       obstack_1grow (&solved_conflicts_obstack
, '\0'); 
 252       s
->solved_conflicts 
= obstack_finish (&solved_conflicts_obstack
); 
 257 /*-------------------------------------------------------------------. 
 258 | Solve the S/R conflicts of state S using the                       | 
 259 | precedence/associativity, and flag it inconsistent if it still has | 
 260 | conflicts.  ERRORS can be used as storage to compute the list of   | 
 261 | look-ahead tokens on which S raises a syntax error (%nonassoc).    | 
 262 `-------------------------------------------------------------------*/ 
 265 set_conflicts (state 
*s
, symbol 
**errors
) 
 268   transitions 
*trans 
= s
->transitions
; 
 269   reductions 
*reds 
= s
->reductions
; 
 274   bitset_zero (look_ahead_set
); 
 276   FOR_EACH_SHIFT (trans
, i
) 
 277     bitset_set (look_ahead_set
, TRANSITION_SYMBOL (trans
, i
)); 
 279   /* Loop over all rules which require look-ahead in this state.  First 
 280      check for shift-reduce conflict, and try to resolve using 
 282   for (i 
= 0; i 
< reds
->num
; ++i
) 
 283     if (reds
->rules
[i
]->prec 
&& reds
->rules
[i
]->prec
->prec
 
 284         && !bitset_disjoint_p (reds
->look_ahead_tokens
[i
], look_ahead_set
)) 
 285       resolve_sr_conflict (s
, i
, errors
); 
 287   /* Loop over all rules which require look-ahead in this state.  Check 
 288      for conflicts not resolved above.  */ 
 289   for (i 
= 0; i 
< reds
->num
; ++i
) 
 291       if (!bitset_disjoint_p (reds
->look_ahead_tokens
[i
], look_ahead_set
)) 
 292         conflicts
[s
->number
] = 1; 
 294       bitset_or (look_ahead_set
, look_ahead_set
, reds
->look_ahead_tokens
[i
]); 
 299 /*----------------------------------------------------------------. 
 300 | Solve all the S/R conflicts using the precedence/associativity, | 
 301 | and flag as inconsistent the states that still have conflicts.  | 
 302 `----------------------------------------------------------------*/ 
 305 conflicts_solve (void) 
 308   /* List of look-ahead tokens on which we explicitly raise a syntax error.  */ 
 309   symbol 
**errors 
= xnmalloc (ntokens 
+ 1, sizeof *errors
); 
 311   conflicts 
= xcalloc (nstates
, sizeof *conflicts
); 
 312   shift_set 
= bitset_create (ntokens
, BITSET_FIXED
); 
 313   look_ahead_set 
= bitset_create (ntokens
, BITSET_FIXED
); 
 314   obstack_init (&solved_conflicts_obstack
); 
 316   for (i 
= 0; i 
< nstates
; i
++) 
 318       set_conflicts (states
[i
], errors
); 
 320       /* For uniformity of the code, make sure all the states have a valid 
 322       if (!states
[i
]->errs
) 
 323         states
[i
]->errs 
= errs_new (0, 0); 
 330 /*---------------------------------------------. 
 331 | Count the number of shift/reduce conflicts.  | 
 332 `---------------------------------------------*/ 
 335 count_sr_conflicts (state 
*s
) 
 339   transitions 
*trans 
= s
->transitions
; 
 340   reductions 
*reds 
= s
->reductions
; 
 345   bitset_zero (look_ahead_set
); 
 346   bitset_zero (shift_set
); 
 348   FOR_EACH_SHIFT (trans
, i
) 
 349     bitset_set (shift_set
, TRANSITION_SYMBOL (trans
, i
)); 
 351   for (i 
= 0; i 
< reds
->num
; ++i
) 
 352     bitset_or (look_ahead_set
, look_ahead_set
, reds
->look_ahead_tokens
[i
]); 
 354   bitset_and (look_ahead_set
, look_ahead_set
, shift_set
); 
 356   src_count 
= bitset_count (look_ahead_set
); 
 362 /*----------------------------------------------------------------. 
 363 | Count the number of reduce/reduce conflicts.  If ONE_PER_TOKEN, | 
 364 | count one conflict for each token that has any reduce/reduce    | 
 365 | conflicts.  Otherwise, count one conflict for each pair of      | 
 366 | conflicting reductions.                                         | 
 367 +`----------------------------------------------------------------*/ 
 370 count_rr_conflicts (state 
*s
, bool one_per_token
) 
 373   reductions 
*reds 
= s
->reductions
; 
 376   for (i 
= 0; i 
< ntokens
; i
++) 
 380       for (j 
= 0; j 
< reds
->num
; ++j
) 
 381         if (bitset_test (reds
->look_ahead_tokens
[j
], i
)) 
 385         rrc_count 
+= one_per_token 
? 1 : count
-1; 
 392 /*--------------------------------------------------------. 
 393 | Report the number of conflicts, using the Yacc format.  | 
 394 `--------------------------------------------------------*/ 
 397 conflict_report (FILE *out
, int src_num
, int rrc_num
) 
 399   if (src_num 
&& rrc_num
) 
 400     fprintf (out
, _("conflicts: %d shift/reduce, %d reduce/reduce\n"), 
 403     fprintf (out
, _("conflicts: %d shift/reduce\n"), src_num
); 
 405     fprintf (out
, _("conflicts: %d reduce/reduce\n"), rrc_num
); 
 409 /*-----------------------------------------------------------. 
 410 | Output the detailed description of states with conflicts.  | 
 411 `-----------------------------------------------------------*/ 
 414 conflicts_output (FILE *out
) 
 416   bool printed_sth 
= false; 
 418   for (i 
= 0; i 
< nstates
; i
++) 
 420       state 
*s 
= states
[i
]; 
 423           fprintf (out
, _("State %d "), i
); 
 424           conflict_report (out
, count_sr_conflicts (s
), 
 425                            count_rr_conflicts (s
, true)); 
 433 /*--------------------------------------------------------. 
 434 | Total the number of S/R and R/R conflicts.  Unlike the  | 
 435 | code in conflicts_output, however, count EACH pair of   | 
 436 | reductions for the same state and look-ahead as one     | 
 438 `--------------------------------------------------------*/ 
 441 conflicts_total_count (void) 
 446   /* Conflicts by state.  */ 
 448   for (i 
= 0; i 
< nstates
; i
++) 
 451         count 
+= count_sr_conflicts (states
[i
]); 
 452         count 
+= count_rr_conflicts (states
[i
], false); 
 458 /*------------------------------------------. 
 459 | Reporting the total number of conflicts.  | 
 460 `------------------------------------------*/ 
 463 conflicts_print (void) 
 465   /* Is the number of SR conflicts OK?  Either EXPECTED_CONFLICTS is 
 466      not set, and then we want 0 SR, or else it is specified, in which 
 467      case we want equality.  */ 
 476   /* Conflicts by state.  */ 
 480     for (i 
= 0; i 
< nstates
; i
++) 
 483           src_total 
+= count_sr_conflicts (states
[i
]); 
 484           rrc_total 
+= count_rr_conflicts (states
[i
], true); 
 488   if (! glr_parser 
&& rrc_total 
> 0 && expected_rr_conflicts 
!= -1) 
 490       warn (_("%%expect-rr applies only to GLR parsers")); 
 491       expected_rr_conflicts 
= -1; 
 494   src_expected 
= expected_sr_conflicts 
== -1 ? 0 : expected_sr_conflicts
; 
 495   rrc_expected 
= expected_rr_conflicts 
== -1 ? 0 : expected_rr_conflicts
; 
 496   src_ok 
= src_total 
== src_expected
; 
 497   rrc_ok 
= rrc_total 
== rrc_expected
; 
 499   /* If there are as many RR conflicts and SR conflicts as 
 500      expected, then there is nothing to report.  */ 
 504   /* Report the total number of conflicts on STDERR.  */ 
 505   if (src_total 
| rrc_total
) 
 508         fprintf (stderr
, "%s: ", current_file
); 
 509       conflict_report (stderr
, src_total
, rrc_total
); 
 512   if (expected_sr_conflicts 
!= -1 || expected_rr_conflicts 
!= -1) 
 515         complain (ngettext ("expected %d shift/reduce conflict", 
 516                             "expected %d shift/reduce conflicts", 
 520         complain (ngettext ("expected %d reduce/reduce conflict", 
 521                             "expected %d reduce/reduce conflicts", 
 529 conflicts_free (void) 
 532   bitset_free (shift_set
); 
 533   bitset_free (look_ahead_set
); 
 534   obstack_free (&solved_conflicts_obstack
, NULL
);