]>
git.saurik.com Git - bison.git/blob - src/conflicts.c
1 /* Find and resolve or report look-ahead conflicts for bison,
2 Copyright (C) 1984, 1989, 1992 Free Software Foundation, Inc.
4 This file is part of Bison, the GNU Compiler Compiler.
6 Bison is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 Bison is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
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
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
31 extern int tokensetsize
;
32 extern char *consistent
;
33 extern short *accessing_symbol
;
34 extern shifts
**shift_table
;
36 extern short *LAruleno
;
37 extern short *lookaheads
;
38 extern int verboseflag
;
39 extern int fixed_outfiles
;
41 extern void initialize_conflicts
PARAMS((void));
42 extern void conflict_log
PARAMS((void));
43 extern void verbose_conflict_log
PARAMS((void));
44 extern void print_reductions
PARAMS((int));
45 extern void finalize_conflicts
PARAMS((void));
47 static void set_conflicts
PARAMS((int));
48 static void resolve_sr_conflict
PARAMS((int, int));
49 static void flush_shift
PARAMS((int, int));
50 static void log_resolution
PARAMS((int, int, int, char *));
51 static void total_conflicts
PARAMS((void));
52 static void count_sr_conflicts
PARAMS((int));
53 static void count_rr_conflicts
PARAMS((int));
57 int expected_conflicts
;
58 static char *conflicts
;
61 static unsigned *shiftset
;
62 static unsigned *lookaheadset
;
70 initialize_conflicts (void)
73 /* register errs *sp; JF unused */
75 conflicts
= NEW2(nstates
, char);
76 shiftset
= NEW2(tokensetsize
, unsigned);
77 lookaheadset
= NEW2(tokensetsize
, unsigned);
79 err_table
= NEW2(nstates
, errs
*);
83 for (i
= 0; i
< nstates
; i
++)
89 set_conflicts (int state
)
93 register shifts
*shiftp
;
94 register unsigned *fp2
;
95 register unsigned *fp3
;
96 register unsigned *fp4
;
97 register unsigned *fp1
;
100 if (consistent
[state
]) return;
102 for (i
= 0; i
< tokensetsize
; i
++)
105 shiftp
= shift_table
[state
];
109 for (i
= 0; i
< k
; i
++)
111 symbol
= accessing_symbol
[shiftp
->shifts
[i
]];
112 if (ISVAR(symbol
)) break;
113 SETBIT(lookaheadset
, symbol
);
117 k
= lookaheads
[state
+ 1];
118 fp4
= lookaheadset
+ tokensetsize
;
120 /* loop over all rules which require lookahead in this state */
121 /* first check for shift-reduce conflict, and try to resolve using precedence */
123 for (i
= lookaheads
[state
]; i
< k
; i
++)
124 if (rprec
[LAruleno
[i
]])
126 fp1
= LA
+ i
* tokensetsize
;
134 resolve_sr_conflict(state
, i
);
140 /* loop over all rules which require lookahead in this state */
141 /* Check for conflicts not resolved above. */
143 for (i
= lookaheads
[state
]; i
< k
; i
++)
145 fp1
= LA
+ i
* tokensetsize
;
153 conflicts
[state
] = 1;
168 /* Attempt to resolve shift-reduce conflict for one rule
169 by means of precedence declarations.
170 It has already been checked that the rule has a precedence.
171 A conflict is resolved by modifying the shift or reduce tables
172 so that there is no longer a conflict. */
175 resolve_sr_conflict (int state
, int lookaheadnum
)
179 register unsigned *fp1
;
180 register unsigned *fp2
;
181 register int redprec
;
182 errs
*errp
= (errs
*) xmalloc (sizeof(errs
) + ntokens
* sizeof(short));
183 short *errtokens
= errp
->errs
;
185 /* find the rule to reduce by to get precedence of reduction */
186 redprec
= rprec
[LAruleno
[lookaheadnum
]];
189 fp1
= LA
+ lookaheadnum
* tokensetsize
;
191 for (i
= 0; i
< ntokens
; i
++)
193 if ((mask
& *fp2
& *fp1
) && sprec
[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. */
198 if (sprec
[i
] < redprec
)
200 if (verboseflag
) log_resolution(state
, lookaheadnum
, i
, _("reduce"));
201 *fp2
&= ~mask
; /* flush the shift for this token */
202 flush_shift(state
, i
);
204 else if (sprec
[i
] > redprec
)
206 if (verboseflag
) log_resolution(state
, lookaheadnum
, i
, _("shift"));
207 *fp1
&= ~mask
; /* flush the reduce for this token */
211 /* Matching precedence levels.
212 For left association, keep only the reduction.
213 For right association, keep only the shift.
214 For nonassociation, keep neither. */
220 if (verboseflag
) log_resolution(state
, lookaheadnum
, i
, _("shift"));
224 if (verboseflag
) log_resolution(state
, lookaheadnum
, i
, _("reduce"));
228 if (verboseflag
) log_resolution(state
, lookaheadnum
, i
, _("an error"));
232 if (sassoc
[i
] != RIGHT_ASSOC
)
234 *fp2
&= ~mask
; /* flush the shift for this token */
235 flush_shift(state
, i
);
237 if (sassoc
[i
] != LEFT_ASSOC
)
239 *fp1
&= ~mask
; /* flush the reduce for this token */
241 if (sassoc
[i
] == NON_ASSOC
)
243 /* Record an explicit error for this token. */
256 errp
->nerrs
= errtokens
- errp
->errs
;
259 /* Some tokens have been explicitly made errors. Allocate
260 a permanent errs structure for this state, to record them. */
261 i
= (char *) errtokens
- (char *) errp
;
262 err_table
[state
] = (errs
*) xmalloc ((unsigned int)i
);
263 bcopy (errp
, err_table
[state
], i
);
266 err_table
[state
] = 0;
272 /* turn off the shift recorded for the specified token in the specified state.
273 Used when we resolve a shift-reduce conflict in favor of the reduction. */
276 flush_shift (int state
, int token
)
278 register shifts
*shiftp
;
280 /* register unsigned symbol; JF unused */
282 shiftp
= shift_table
[state
];
287 for (i
= 0; i
< k
; i
++)
289 if (shiftp
->shifts
[i
] && token
== accessing_symbol
[shiftp
->shifts
[i
]])
290 (shiftp
->shifts
[i
]) = 0;
297 log_resolution (int state
, int LAno
, int token
, char *resolution
)
300 _("Conflict in state %d between rule %d and token %s resolved as %s.\n"),
301 state
, LAruleno
[LAno
], tags
[token
], resolution
);
313 for (i
= 0; i
< nstates
; i
++)
317 count_sr_conflicts(i
);
318 count_rr_conflicts(i
);
319 src_total
+= src_count
;
320 rrc_total
+= rrc_count
;
329 verbose_conflict_log (void)
336 for (i
= 0; i
< nstates
; i
++)
340 count_sr_conflicts(i
);
341 count_rr_conflicts(i
);
342 src_total
+= src_count
;
343 rrc_total
+= rrc_count
;
345 fprintf(foutput
, _("State %d contains"), i
);
348 fprintf(foutput
, _(" 1 shift/reduce conflict"));
349 else if (src_count
> 1)
350 fprintf(foutput
, _(" %d shift/reduce conflicts"), src_count
);
352 if (src_count
> 0 && rrc_count
> 0)
353 fprintf(foutput
, _(" and"));
356 fprintf(foutput
, _(" 1 reduce/reduce conflict"));
357 else if (rrc_count
> 1)
358 fprintf(foutput
, _(" %d reduce/reduce conflicts"), rrc_count
);
370 total_conflicts (void)
372 if (src_total
== expected_conflicts
&& rrc_total
== 0)
377 /* If invoked under the name `yacc', use the output format
378 specified by POSIX. */
379 fprintf(stderr
, _("conflicts: "));
381 fprintf(stderr
, _(" %d shift/reduce"), src_total
);
382 if (src_total
> 0 && rrc_total
> 0)
383 fprintf(stderr
, ",");
385 fprintf(stderr
, _(" %d reduce/reduce"), rrc_total
);
390 fprintf(stderr
, _("%s contains"), infile
);
393 fprintf(stderr
, _(" 1 shift/reduce conflict"));
394 else if (src_total
> 1)
395 fprintf(stderr
, _(" %d shift/reduce conflicts"), src_total
);
397 if (src_total
> 0 && rrc_total
> 0)
398 fprintf(stderr
, _(" and"));
401 fprintf(stderr
, _(" 1 reduce/reduce conflict"));
402 else if (rrc_total
> 1)
403 fprintf(stderr
, _(" %d reduce/reduce conflicts"), rrc_total
);
412 count_sr_conflicts (int state
)
417 register shifts
*shiftp
;
418 register unsigned *fp1
;
419 register unsigned *fp2
;
420 register unsigned *fp3
;
425 shiftp
= shift_table
[state
];
428 for (i
= 0; i
< tokensetsize
; i
++)
435 for (i
= 0; i
< k
; i
++)
437 if (! shiftp
->shifts
[i
]) continue;
438 symbol
= accessing_symbol
[shiftp
->shifts
[i
]];
439 if (ISVAR(symbol
)) break;
440 SETBIT(shiftset
, symbol
);
443 k
= lookaheads
[state
+ 1];
444 fp3
= lookaheadset
+ tokensetsize
;
446 for (i
= lookaheads
[state
]; i
< k
; i
++)
448 fp1
= LA
+ i
* tokensetsize
;
463 for (i
= 0; i
< ntokens
; i
++)
479 count_rr_conflicts (int state
)
484 register unsigned mask
;
485 register unsigned *baseword
;
486 register unsigned *wordp
;
492 m
= lookaheads
[state
];
493 n
= lookaheads
[state
+ 1];
495 if (n
- m
< 2) return;
498 baseword
= LA
+ m
* tokensetsize
;
499 for (i
= 0; i
< ntokens
; i
++)
504 for (j
= m
; j
< n
; j
++)
509 wordp
+= tokensetsize
;
512 if (count
>= 2) rrc_count
++;
525 print_reductions (int state
)
530 register unsigned *fp1
;
531 register unsigned *fp2
;
532 register unsigned *fp3
;
533 register unsigned *fp4
;
536 register unsigned mask
;
539 register int default_LA
;
540 register int default_rule
= 0;
543 register shifts
*shiftp
;
547 for (i
= 0; i
< tokensetsize
; i
++)
550 shiftp
= shift_table
[state
];
554 for (i
= 0; i
< k
; i
++)
556 if (! shiftp
->shifts
[i
]) continue;
557 symbol
= accessing_symbol
[shiftp
->shifts
[i
]];
558 if (ISVAR(symbol
)) break;
559 /* if this state has a shift for the error token,
560 don't use a default rule. */
561 if (symbol
== error_token_number
) nodefault
= 1;
562 SETBIT(shiftset
, symbol
);
566 errp
= err_table
[state
];
570 for (i
= 0; i
< k
; i
++)
572 if (! errp
->errs
[i
]) continue;
573 symbol
= errp
->errs
[i
];
574 SETBIT(shiftset
, symbol
);
578 m
= lookaheads
[state
];
579 n
= lookaheads
[state
+ 1];
581 if (n
- m
== 1 && ! nodefault
)
583 default_rule
= LAruleno
[m
];
585 fp1
= LA
+ m
* tokensetsize
;
588 fp4
= lookaheadset
+ tokensetsize
;
591 *fp3
++ = *fp1
++ & *fp2
++;
596 for (i
= 0; i
< ntokens
; i
++)
599 fprintf(foutput
, _(" %-4s\t[reduce using rule %d (%s)]\n"),
600 tags
[i
], default_rule
, tags
[rlhs
[default_rule
]]);
610 fprintf(foutput
, _(" $default\treduce using rule %d (%s)\n\n"),
611 default_rule
, tags
[rlhs
[default_rule
]]);
617 fp4
= lookaheadset
+ tokensetsize
;
620 for (i
= m
; i
< n
; i
++)
622 fp1
= LA
+ i
* tokensetsize
;
627 *fp3
++ = *fp1
++ & (~(*fp2
++));
632 for (j
= 0; j
< ntokens
; j
++)
649 default_rule
= LAruleno
[i
];
659 for (i
= 0; i
< tokensetsize
; i
++)
665 for (i
= 0; i
< k
; i
++)
667 if (! shiftp
->shifts
[i
]) continue;
668 symbol
= accessing_symbol
[shiftp
->shifts
[i
]];
669 if (ISVAR(symbol
)) break;
670 SETBIT(shiftset
, symbol
);
675 fp1
= LA
+ m
* tokensetsize
;
677 for (i
= 0; i
< ntokens
; i
++)
687 for (j
= m
; j
< n
; j
++)
696 fprintf(foutput
, _(" %-4s\treduce using rule %d (%s)\n"),
697 tags
[i
], rule
, tags
[rlhs
[rule
]]);
707 rule
= LAruleno
[default_LA
];
708 fprintf(foutput
, _(" %-4s\treduce using rule %d (%s)\n"),
709 tags
[i
], rule
, tags
[rlhs
[rule
]]);
713 fprintf(foutput
, _(" %-4s\t[reduce using rule %d (%s)]\n"),
714 tags
[i
], rule
, tags
[rlhs
[rule
]]);
725 /* We tried incrementing just fp1, and just fp2; both seem wrong.
726 It seems necessary to increment both in sync. */
734 fprintf(foutput
, _(" $default\treduce using rule %d (%s)\n"),
735 default_rule
, tags
[rlhs
[default_rule
]]);
744 finalize_conflicts (void)