1 /* Find and resolve or report lookahead conflicts for bison, 
   3    Copyright (C) 1984, 1989, 1992, 2000-2010 Free Software Foundation, 
   6    This file is part of Bison, the GNU Compiler Compiler. 
   8    This program is free software: you can redistribute it and/or modify 
   9    it under the terms of the GNU General Public License as published by 
  10    the Free Software Foundation, either version 3 of the License, or 
  11    (at your option) any later version. 
  13    This program is distributed in the hope that it will be useful, 
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of 
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  16    GNU General Public License for more details. 
  18    You should have received a copy of the GNU General Public License 
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ 
  28 #include "conflicts.h" 
  33 #include "print-xml.h" 
  38 /* -1 stands for not specified. */ 
  39 int expected_sr_conflicts 
= -1; 
  40 int expected_rr_conflicts 
= -1; 
  41 static char *conflicts
; 
  42 static struct obstack solved_conflicts_obstack
; 
  43 static struct obstack solved_conflicts_xml_obstack
; 
  45 static bitset shift_set
; 
  46 static bitset lookahead_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
, 
  77                           _("    Conflict between rule %d and token %s" 
  78                             " resolved as shift"), 
  83         case reduce_resolution
: 
  85           obstack_fgrow2 (&solved_conflicts_obstack
, 
  86                           _("    Conflict between rule %d and token %s" 
  87                             " resolved as reduce"), 
  92         case nonassoc_resolution
: 
  93           obstack_fgrow2 (&solved_conflicts_obstack
, 
  94                           _("    Conflict between rule %d and token %s" 
  95                             " resolved as an error"), 
 104         case shift_resolution
: 
 105           obstack_fgrow2 (&solved_conflicts_obstack
, 
 108                           symbols
[token
]->tag
); 
 111         case reduce_resolution
: 
 112           obstack_fgrow2 (&solved_conflicts_obstack
, 
 118         case left_resolution
: 
 119           obstack_fgrow1 (&solved_conflicts_obstack
, 
 121                           symbols
[token
]->tag
); 
 124         case right_resolution
: 
 125           obstack_fgrow1 (&solved_conflicts_obstack
, 
 127                           symbols
[token
]->tag
); 
 130         case nonassoc_resolution
: 
 131           obstack_fgrow1 (&solved_conflicts_obstack
, 
 133                           symbols
[token
]->tag
); 
 137       obstack_sgrow (&solved_conflicts_obstack
, ".\n"); 
 143       /* The description of the resolution. */ 
 146         case shift_resolution
: 
 147         case right_resolution
: 
 148           obstack_fgrow2 (&solved_conflicts_xml_obstack
, 
 149                           "        <resolution rule=\"%d\" symbol=\"%s\"" 
 152                           xml_escape (symbols
[token
]->tag
)); 
 155         case reduce_resolution
: 
 156         case left_resolution
: 
 157           obstack_fgrow2 (&solved_conflicts_xml_obstack
, 
 158                           "        <resolution rule=\"%d\" symbol=\"%s\"" 
 161                           xml_escape (symbols
[token
]->tag
)); 
 164         case nonassoc_resolution
: 
 165           obstack_fgrow2 (&solved_conflicts_xml_obstack
, 
 166                           "        <resolution rule=\"%d\" symbol=\"%s\"" 
 169                           xml_escape (symbols
[token
]->tag
)); 
 176         case shift_resolution
: 
 177           obstack_fgrow2 (&solved_conflicts_xml_obstack
, 
 179                           xml_escape_n (0, r
->prec
->tag
), 
 180                           xml_escape_n (1, symbols
[token
]->tag
)); 
 183         case reduce_resolution
: 
 184           obstack_fgrow2 (&solved_conflicts_xml_obstack
, 
 186                           xml_escape_n (0, symbols
[token
]->tag
), 
 187                           xml_escape_n (1, r
->prec
->tag
)); 
 190         case left_resolution
: 
 191           obstack_fgrow1 (&solved_conflicts_xml_obstack
, 
 193                           xml_escape (symbols
[token
]->tag
)); 
 196         case right_resolution
: 
 197           obstack_fgrow1 (&solved_conflicts_xml_obstack
, 
 199                           xml_escape (symbols
[token
]->tag
)); 
 202         case nonassoc_resolution
: 
 203           obstack_fgrow1 (&solved_conflicts_xml_obstack
, 
 205                           xml_escape (symbols
[token
]->tag
)); 
 209       obstack_sgrow (&solved_conflicts_xml_obstack
, "</resolution>\n"); 
 214 /*------------------------------------------------------------------. 
 215 | Turn off the shift recorded for the specified token in the        | 
 216 | specified state.  Used when we resolve a shift-reduce conflict in | 
 217 | favor of the reduction or as an error (%nonassoc).                | 
 218 `------------------------------------------------------------------*/ 
 221 flush_shift (state 
*s
, int token
) 
 223   transitions 
*trans 
= s
->transitions
; 
 226   bitset_reset (lookahead_set
, token
); 
 227   for (i 
= 0; i 
< trans
->num
; i
++) 
 228     if (!TRANSITION_IS_DISABLED (trans
, i
) 
 229         && TRANSITION_SYMBOL (trans
, i
) == token
) 
 230       TRANSITION_DISABLE (trans
, i
); 
 234 /*--------------------------------------------------------------------. 
 235 | Turn off the reduce recorded for the specified token in the         | 
 236 | specified lookahead set.  Used when we resolve a shift-reduce       | 
 237 | conflict in favor of the shift or as an error (%nonassoc).          | 
 238 `--------------------------------------------------------------------*/ 
 241 flush_reduce (bitset lookahead_tokens
, int token
) 
 243   bitset_reset (lookahead_tokens
, token
); 
 247 /*------------------------------------------------------------------. 
 248 | Attempt to resolve shift-reduce conflict for one rule by means of | 
 249 | precedence declarations.  It has already been checked that the    | 
 250 | rule has a precedence.  A conflict is resolved by modifying the   | 
 251 | shift or reduce tables so that there is no longer a conflict.     | 
 253 | RULENO is the number of the lookahead bitset to consider.         | 
 255 | ERRORS and NERRS can be used to store discovered explicit         | 
 257 `------------------------------------------------------------------*/ 
 260 resolve_sr_conflict (state 
*s
, int ruleno
, symbol 
**errors
, int *nerrs
) 
 263   reductions 
*reds 
= s
->reductions
; 
 264   /* Find the rule to reduce by to get precedence of reduction.  */ 
 265   rule 
*redrule 
= reds
->rules
[ruleno
]; 
 266   int redprec 
= redrule
->prec
->prec
; 
 267   bitset lookahead_tokens 
= reds
->lookahead_tokens
[ruleno
]; 
 269   for (i 
= 0; i 
< ntokens
; i
++) 
 270     if (bitset_test (lookahead_tokens
, i
) 
 271         && bitset_test (lookahead_set
, i
) 
 274         /* Shift-reduce conflict occurs for token number i 
 275            and it has a precedence. 
 276            The precedence of shifting is that of token i.  */ 
 277         if (symbols
[i
]->prec 
< redprec
) 
 279             log_resolution (redrule
, i
, reduce_resolution
); 
 282         else if (symbols
[i
]->prec 
> redprec
) 
 284             log_resolution (redrule
, i
, shift_resolution
); 
 285             flush_reduce (lookahead_tokens
, i
); 
 288           /* Matching precedence levels. 
 289              For non-defined associativity, keep both: unexpected 
 290              associativity conflict. 
 291              For left associativity, keep only the reduction. 
 292              For right associativity, keep only the shift. 
 293              For nonassociativity, keep neither.  */ 
 295           switch (symbols
[i
]->assoc
) 
 300             case precedence_assoc
: 
 304               log_resolution (redrule
, i
, right_resolution
); 
 305               flush_reduce (lookahead_tokens
, i
); 
 309               log_resolution (redrule
, i
, left_resolution
); 
 314               log_resolution (redrule
, i
, nonassoc_resolution
); 
 316               flush_reduce (lookahead_tokens
, i
); 
 317               /* Record an explicit error for this token.  */ 
 318               errors
[(*nerrs
)++] = symbols
[i
]; 
 325 /*-------------------------------------------------------------------. 
 326 | Solve the S/R conflicts of state S using the                       | 
 327 | precedence/associativity, and flag it inconsistent if it still has | 
 328 | conflicts.  ERRORS can be used as storage to compute the list of   | 
 329 | lookahead tokens on which S raises a syntax error (%nonassoc).     | 
 330 `-------------------------------------------------------------------*/ 
 333 set_conflicts (state 
*s
, symbol 
**errors
) 
 336   transitions 
*trans 
= s
->transitions
; 
 337   reductions 
*reds 
= s
->reductions
; 
 343   bitset_zero (lookahead_set
); 
 345   FOR_EACH_SHIFT (trans
, i
) 
 346     bitset_set (lookahead_set
, TRANSITION_SYMBOL (trans
, i
)); 
 348   /* Loop over all rules which require lookahead in this state.  First 
 349      check for shift-reduce conflict, and try to resolve using 
 351   for (i 
= 0; i 
< reds
->num
; ++i
) 
 352     if (reds
->rules
[i
]->prec 
&& reds
->rules
[i
]->prec
->prec
 
 353         && !bitset_disjoint_p (reds
->lookahead_tokens
[i
], lookahead_set
)) 
 354       resolve_sr_conflict (s
, i
, errors
, &nerrs
); 
 358       /* Some tokens have been explicitly made errors.  Allocate a 
 359          permanent errs structure for this state, to record them.  */ 
 360       state_errs_set (s
, nerrs
, errors
); 
 362   if (obstack_object_size (&solved_conflicts_obstack
)) 
 364       obstack_1grow (&solved_conflicts_obstack
, '\0'); 
 365       s
->solved_conflicts 
= obstack_finish (&solved_conflicts_obstack
); 
 367   if (obstack_object_size (&solved_conflicts_xml_obstack
)) 
 369       obstack_1grow (&solved_conflicts_xml_obstack
, '\0'); 
 370       s
->solved_conflicts_xml 
= obstack_finish (&solved_conflicts_xml_obstack
); 
 373   /* Loop over all rules which require lookahead in this state.  Check 
 374      for conflicts not resolved above.  */ 
 375   for (i 
= 0; i 
< reds
->num
; ++i
) 
 377       if (!bitset_disjoint_p (reds
->lookahead_tokens
[i
], lookahead_set
)) 
 378         conflicts
[s
->number
] = 1; 
 379       bitset_or (lookahead_set
, lookahead_set
, reds
->lookahead_tokens
[i
]); 
 384 /*----------------------------------------------------------------. 
 385 | Solve all the S/R conflicts using the precedence/associativity, | 
 386 | and flag as inconsistent the states that still have conflicts.  | 
 387 `----------------------------------------------------------------*/ 
 390 conflicts_solve (void) 
 393   /* List of lookahead tokens on which we explicitly raise a syntax error.  */ 
 394   symbol 
**errors 
= xnmalloc (ntokens 
+ 1, sizeof *errors
); 
 396   conflicts 
= xcalloc (nstates
, sizeof *conflicts
); 
 397   shift_set 
= bitset_create (ntokens
, BITSET_FIXED
); 
 398   lookahead_set 
= bitset_create (ntokens
, BITSET_FIXED
); 
 399   obstack_init (&solved_conflicts_obstack
); 
 400   obstack_init (&solved_conflicts_xml_obstack
); 
 402   for (i 
= 0; i 
< nstates
; i
++) 
 404       set_conflicts (states
[i
], errors
); 
 406       /* For uniformity of the code, make sure all the states have a valid 
 408       if (!states
[i
]->errs
) 
 409         states
[i
]->errs 
= errs_new (0, 0); 
 417 conflicts_update_state_numbers (state_number old_to_new
[], 
 418                                 state_number nstates_old
) 
 421   for (i 
= 0; i 
< nstates_old
; ++i
) 
 422     if (old_to_new
[i
] != nstates_old
) 
 423       conflicts
[old_to_new
[i
]] = conflicts
[i
]; 
 427 /*---------------------------------------------. 
 428 | Count the number of shift/reduce conflicts.  | 
 429 `---------------------------------------------*/ 
 432 count_sr_conflicts (state 
*s
) 
 436   transitions 
*trans 
= s
->transitions
; 
 437   reductions 
*reds 
= s
->reductions
; 
 442   bitset_zero (lookahead_set
); 
 443   bitset_zero (shift_set
); 
 445   FOR_EACH_SHIFT (trans
, i
) 
 446     bitset_set (shift_set
, TRANSITION_SYMBOL (trans
, i
)); 
 448   for (i 
= 0; i 
< reds
->num
; ++i
) 
 449     bitset_or (lookahead_set
, lookahead_set
, reds
->lookahead_tokens
[i
]); 
 451   bitset_and (lookahead_set
, lookahead_set
, shift_set
); 
 453   src_count 
= bitset_count (lookahead_set
); 
 459 /*----------------------------------------------------------------. 
 460 | Count the number of reduce/reduce conflicts.  If ONE_PER_TOKEN, | 
 461 | count one conflict for each token that has any reduce/reduce    | 
 462 | conflicts.  Otherwise, count one conflict for each pair of      | 
 463 | conflicting reductions.                                         | 
 464 +`----------------------------------------------------------------*/ 
 467 count_rr_conflicts (state 
*s
, bool one_per_token
) 
 470   reductions 
*reds 
= s
->reductions
; 
 473   for (i 
= 0; i 
< ntokens
; i
++) 
 477       for (j 
= 0; j 
< reds
->num
; ++j
) 
 478         if (bitset_test (reds
->lookahead_tokens
[j
], i
)) 
 482         rrc_count 
+= one_per_token 
? 1 : count
-1; 
 489 /*--------------------------------------------------------. 
 490 | Report the number of conflicts, using the Yacc format.  | 
 491 `--------------------------------------------------------*/ 
 494 conflict_report (FILE *out
, int src_num
, int rrc_num
) 
 496   if (src_num 
&& rrc_num
) 
 497     fprintf (out
, _("conflicts: %d shift/reduce, %d reduce/reduce\n"), 
 500     fprintf (out
, _("conflicts: %d shift/reduce\n"), src_num
); 
 502     fprintf (out
, _("conflicts: %d reduce/reduce\n"), rrc_num
); 
 506 /*-----------------------------------------------------------. 
 507 | Output the detailed description of states with conflicts.  | 
 508 `-----------------------------------------------------------*/ 
 511 conflicts_output (FILE *out
) 
 513   bool printed_sth 
= false; 
 515   for (i 
= 0; i 
< nstates
; i
++) 
 517       state 
*s 
= states
[i
]; 
 520           fprintf (out
, _("State %d "), i
); 
 521           conflict_report (out
, count_sr_conflicts (s
), 
 522                            count_rr_conflicts (s
, true)); 
 530 /*--------------------------------------------------------. 
 531 | Total the number of S/R and R/R conflicts.  Unlike the  | 
 532 | code in conflicts_output, however, count EACH pair of   | 
 533 | reductions for the same state and lookahead as one      | 
 535 `--------------------------------------------------------*/ 
 538 conflicts_total_count (void) 
 543   /* Conflicts by state.  */ 
 545   for (i 
= 0; i 
< nstates
; i
++) 
 548         count 
+= count_sr_conflicts (states
[i
]); 
 549         count 
+= count_rr_conflicts (states
[i
], false); 
 555 /*------------------------------------------. 
 556 | Reporting the total number of conflicts.  | 
 557 `------------------------------------------*/ 
 560 conflicts_print (void) 
 562   /* Is the number of SR conflicts OK?  Either EXPECTED_CONFLICTS is 
 563      not set, and then we want 0 SR, or else it is specified, in which 
 564      case we want equality.  */ 
 573   /* Conflicts by state.  */ 
 577     for (i 
= 0; i 
< nstates
; i
++) 
 580           src_total 
+= count_sr_conflicts (states
[i
]); 
 581           rrc_total 
+= count_rr_conflicts (states
[i
], true); 
 585   if (! glr_parser 
&& rrc_total 
> 0 && expected_rr_conflicts 
!= -1) 
 587       warn (_("%%expect-rr applies only to GLR parsers")); 
 588       expected_rr_conflicts 
= -1; 
 591   src_expected 
= expected_sr_conflicts 
== -1 ? 0 : expected_sr_conflicts
; 
 592   rrc_expected 
= expected_rr_conflicts 
== -1 ? 0 : expected_rr_conflicts
; 
 593   src_ok 
= src_total 
== src_expected
; 
 594   rrc_ok 
= rrc_total 
== rrc_expected
; 
 596   /* If there are as many RR conflicts and SR conflicts as 
 597      expected, then there is nothing to report.  */ 
 601   /* Report the total number of conflicts on STDERR.  */ 
 602   if (src_total 
| rrc_total
) 
 605         fprintf (stderr
, "%s: ", current_file
); 
 606       conflict_report (stderr
, src_total
, rrc_total
); 
 609   if (expected_sr_conflicts 
!= -1 || expected_rr_conflicts 
!= -1) 
 612         complain (ngettext ("expected %d shift/reduce conflict", 
 613                             "expected %d shift/reduce conflicts", 
 617         complain (ngettext ("expected %d reduce/reduce conflict", 
 618                             "expected %d reduce/reduce conflicts", 
 626 conflicts_free (void) 
 629   bitset_free (shift_set
); 
 630   bitset_free (lookahead_set
); 
 631   obstack_free (&solved_conflicts_obstack
, NULL
); 
 632   obstack_free (&solved_conflicts_xml_obstack
, NULL
);