]>
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
30 extern int tokensetsize
;
31 extern char *consistent
;
32 extern short *accessing_symbol
;
33 extern shifts
**shift_table
;
35 extern short *LAruleno
;
36 extern short *lookaheads
;
37 extern int verboseflag
;
40 void resolve_sr_conflict();
42 void log_resolution();
43 void total_conflicts();
44 void count_sr_conflicts();
45 void count_rr_conflicts();
50 int expected_conflicts
;
53 static unsigned *shiftset
;
54 static unsigned *lookaheadset
;
62 initialize_conflicts()
65 /* register errs *sp; JF unused */
67 conflicts
= NEW2(nstates
, char);
68 shiftset
= NEW2(tokensetsize
, unsigned);
69 lookaheadset
= NEW2(tokensetsize
, unsigned);
71 err_table
= NEW2(nstates
, errs
*);
75 for (i
= 0; i
< nstates
; i
++)
86 register shifts
*shiftp
;
87 register unsigned *fp2
;
88 register unsigned *fp3
;
89 register unsigned *fp4
;
90 register unsigned *fp1
;
93 if (consistent
[state
]) return;
95 for (i
= 0; i
< tokensetsize
; i
++)
98 shiftp
= shift_table
[state
];
102 for (i
= 0; i
< k
; i
++)
104 symbol
= accessing_symbol
[shiftp
->shifts
[i
]];
105 if (ISVAR(symbol
)) break;
106 SETBIT(lookaheadset
, symbol
);
110 k
= lookaheads
[state
+ 1];
111 fp4
= lookaheadset
+ tokensetsize
;
113 /* loop over all rules which require lookahead in this state */
114 /* first check for shift-reduce conflict, and try to resolve using precedence */
116 for (i
= lookaheads
[state
]; i
< k
; i
++)
117 if (rprec
[LAruleno
[i
]])
119 fp1
= LA
+ i
* tokensetsize
;
127 resolve_sr_conflict(state
, i
);
133 /* loop over all rules which require lookahead in this state */
134 /* Check for conflicts not resolved above. */
136 for (i
= lookaheads
[state
]; i
< k
; i
++)
138 fp1
= LA
+ i
* tokensetsize
;
146 conflicts
[state
] = 1;
161 /* Attempt to resolve shift-reduce conflict for one rule
162 by means of precedence declarations.
163 It has already been checked that the rule has a precedence.
164 A conflict is resolved by modifying the shift or reduce tables
165 so that there is no longer a conflict. */
168 resolve_sr_conflict(state
, lookaheadnum
)
174 register unsigned *fp1
;
175 register unsigned *fp2
;
176 register int redprec
;
177 errs
*errp
= (errs
*) xmalloc (sizeof(errs
) + ntokens
* sizeof(short));
178 short *errtokens
= errp
->errs
;
180 /* find the rule to reduce by to get precedence of reduction */
181 redprec
= rprec
[LAruleno
[lookaheadnum
]];
184 fp1
= LA
+ lookaheadnum
* tokensetsize
;
186 for (i
= 0; i
< ntokens
; i
++)
188 if ((mask
& *fp2
& *fp1
) && sprec
[i
])
189 /* Shift-reduce conflict occurs for token number i
190 and it has a precedence.
191 The precedence of shifting is that of token i. */
193 if (sprec
[i
] < redprec
)
195 if (verboseflag
) log_resolution(state
, lookaheadnum
, i
, _("reduce"));
196 *fp2
&= ~mask
; /* flush the shift for this token */
197 flush_shift(state
, i
);
199 else if (sprec
[i
] > redprec
)
201 if (verboseflag
) log_resolution(state
, lookaheadnum
, i
, _("shift"));
202 *fp1
&= ~mask
; /* flush the reduce for this token */
206 /* Matching precedence levels.
207 For left association, keep only the reduction.
208 For right association, keep only the shift.
209 For nonassociation, keep neither. */
215 if (verboseflag
) log_resolution(state
, lookaheadnum
, i
, _("shift"));
219 if (verboseflag
) log_resolution(state
, lookaheadnum
, i
, _("reduce"));
223 if (verboseflag
) log_resolution(state
, lookaheadnum
, i
, _("an error"));
227 if (sassoc
[i
] != RIGHT_ASSOC
)
229 *fp2
&= ~mask
; /* flush the shift for this token */
230 flush_shift(state
, i
);
232 if (sassoc
[i
] != LEFT_ASSOC
)
234 *fp1
&= ~mask
; /* flush the reduce for this token */
236 if (sassoc
[i
] == NON_ASSOC
)
238 /* Record an explicit error for this token. */
251 errp
->nerrs
= errtokens
- errp
->errs
;
254 /* Some tokens have been explicitly made errors. Allocate
255 a permanent errs structure for this state, to record them. */
256 i
= (char *) errtokens
- (char *) errp
;
257 err_table
[state
] = (errs
*) xmalloc ((unsigned int)i
);
258 bcopy (errp
, err_table
[state
], i
);
261 err_table
[state
] = 0;
267 /* turn off the shift recorded for the specified token in the specified state.
268 Used when we resolve a shift-reduce conflict in favor of the reduction. */
271 flush_shift(state
, token
)
275 register shifts
*shiftp
;
277 /* register unsigned symbol; JF unused */
279 shiftp
= shift_table
[state
];
284 for (i
= 0; i
< k
; i
++)
286 if (shiftp
->shifts
[i
] && token
== accessing_symbol
[shiftp
->shifts
[i
]])
287 (shiftp
->shifts
[i
]) = 0;
294 log_resolution(state
, LAno
, token
, resolution
)
295 int state
, LAno
, token
;
299 _("Conflict in state %d between rule %d and token %s resolved as %s.\n"),
300 state
, LAruleno
[LAno
], tags
[token
], resolution
);
312 for (i
= 0; i
< nstates
; i
++)
316 count_sr_conflicts(i
);
317 count_rr_conflicts(i
);
318 src_total
+= src_count
;
319 rrc_total
+= rrc_count
;
328 verbose_conflict_log()
335 for (i
= 0; i
< nstates
; i
++)
339 count_sr_conflicts(i
);
340 count_rr_conflicts(i
);
341 src_total
+= src_count
;
342 rrc_total
+= rrc_count
;
344 fprintf(foutput
, _("State %d contains"), i
);
347 fprintf(foutput
, _(" 1 shift/reduce conflict"));
348 else if (src_count
> 1)
349 fprintf(foutput
, _(" %d shift/reduce conflicts"), src_count
);
351 if (src_count
> 0 && rrc_count
> 0)
352 fprintf(foutput
, _(" and"));
355 fprintf(foutput
, _(" 1 reduce/reduce conflict"));
356 else if (rrc_count
> 1)
357 fprintf(foutput
, _(" %d reduce/reduce conflicts"), rrc_count
);
371 extern int fixed_outfiles
;
373 if (src_total
== expected_conflicts
&& rrc_total
== 0)
378 /* If invoked under the name `yacc', use the output format
379 specified by POSIX. */
380 fprintf(stderr
, _("conflicts: "));
382 fprintf(stderr
, _(" %d shift/reduce"), src_total
);
383 if (src_total
> 0 && rrc_total
> 0)
384 fprintf(stderr
, ",");
386 fprintf(stderr
, _(" %d reduce/reduce"), rrc_total
);
391 fprintf(stderr
, _("%s contains"), infile
);
394 fprintf(stderr
, _(" 1 shift/reduce conflict"));
395 else if (src_total
> 1)
396 fprintf(stderr
, _(" %d shift/reduce conflicts"), src_total
);
398 if (src_total
> 0 && rrc_total
> 0)
399 fprintf(stderr
, _(" and"));
402 fprintf(stderr
, _(" 1 reduce/reduce conflict"));
403 else if (rrc_total
> 1)
404 fprintf(stderr
, _(" %d reduce/reduce conflicts"), rrc_total
);
413 count_sr_conflicts(state
)
419 register shifts
*shiftp
;
420 register unsigned *fp1
;
421 register unsigned *fp2
;
422 register unsigned *fp3
;
427 shiftp
= shift_table
[state
];
430 for (i
= 0; i
< tokensetsize
; i
++)
437 for (i
= 0; i
< k
; i
++)
439 if (! shiftp
->shifts
[i
]) continue;
440 symbol
= accessing_symbol
[shiftp
->shifts
[i
]];
441 if (ISVAR(symbol
)) break;
442 SETBIT(shiftset
, symbol
);
445 k
= lookaheads
[state
+ 1];
446 fp3
= lookaheadset
+ tokensetsize
;
448 for (i
= lookaheads
[state
]; i
< k
; i
++)
450 fp1
= LA
+ i
* tokensetsize
;
465 for (i
= 0; i
< ntokens
; i
++)
481 count_rr_conflicts(state
)
487 register unsigned mask
;
488 register unsigned *baseword
;
489 register unsigned *wordp
;
495 m
= lookaheads
[state
];
496 n
= lookaheads
[state
+ 1];
498 if (n
- m
< 2) return;
501 baseword
= LA
+ m
* tokensetsize
;
502 for (i
= 0; i
< ntokens
; i
++)
507 for (j
= m
; j
< n
; j
++)
512 wordp
+= tokensetsize
;
515 if (count
>= 2) rrc_count
++;
528 print_reductions(state
)
534 register unsigned *fp1
;
535 register unsigned *fp2
;
536 register unsigned *fp3
;
537 register unsigned *fp4
;
540 register unsigned mask
;
543 register int default_LA
;
544 register int default_rule
;
547 register shifts
*shiftp
;
551 for (i
= 0; i
< tokensetsize
; i
++)
554 shiftp
= shift_table
[state
];
558 for (i
= 0; i
< k
; i
++)
560 if (! shiftp
->shifts
[i
]) continue;
561 symbol
= accessing_symbol
[shiftp
->shifts
[i
]];
562 if (ISVAR(symbol
)) break;
563 /* if this state has a shift for the error token,
564 don't use a default rule. */
565 if (symbol
== error_token_number
) nodefault
= 1;
566 SETBIT(shiftset
, symbol
);
570 errp
= err_table
[state
];
574 for (i
= 0; i
< k
; i
++)
576 if (! errp
->errs
[i
]) continue;
577 symbol
= errp
->errs
[i
];
578 SETBIT(shiftset
, symbol
);
582 m
= lookaheads
[state
];
583 n
= lookaheads
[state
+ 1];
585 if (n
- m
== 1 && ! nodefault
)
587 default_rule
= LAruleno
[m
];
589 fp1
= LA
+ m
* tokensetsize
;
592 fp4
= lookaheadset
+ tokensetsize
;
595 *fp3
++ = *fp1
++ & *fp2
++;
600 for (i
= 0; i
< ntokens
; i
++)
603 fprintf(foutput
, _(" %-4s\t[reduce using rule %d (%s)]\n"),
604 tags
[i
], default_rule
, tags
[rlhs
[default_rule
]]);
614 fprintf(foutput
, _(" $default\treduce using rule %d (%s)\n\n"),
615 default_rule
, tags
[rlhs
[default_rule
]]);
621 fp4
= lookaheadset
+ tokensetsize
;
624 for (i
= m
; i
< n
; i
++)
626 fp1
= LA
+ i
* tokensetsize
;
631 *fp3
++ = *fp1
++ & (~(*fp2
++));
636 for (j
= 0; j
< ntokens
; j
++)
653 default_rule
= LAruleno
[i
];
663 for (i
= 0; i
< tokensetsize
; i
++)
669 for (i
= 0; i
< k
; i
++)
671 if (! shiftp
->shifts
[i
]) continue;
672 symbol
= accessing_symbol
[shiftp
->shifts
[i
]];
673 if (ISVAR(symbol
)) break;
674 SETBIT(shiftset
, symbol
);
679 fp1
= LA
+ m
* tokensetsize
;
681 for (i
= 0; i
< ntokens
; i
++)
691 for (j
= m
; j
< n
; j
++)
700 fprintf(foutput
, _(" %-4s\treduce using rule %d (%s)\n"),
701 tags
[i
], rule
, tags
[rlhs
[rule
]]);
711 rule
= LAruleno
[default_LA
];
712 fprintf(foutput
, _(" %-4s\treduce using rule %d (%s)\n"),
713 tags
[i
], rule
, tags
[rlhs
[rule
]]);
717 fprintf(foutput
, _(" %-4s\t[reduce using rule %d (%s)]\n"),
718 tags
[i
], rule
, tags
[rlhs
[rule
]]);
729 /* We tried incrementing just fp1, and just fp2; both seem wrong.
730 It seems necessary to increment both in sync. */
738 fprintf(foutput
, _(" $default\treduce using rule %d (%s)\n"),
739 default_rule
, tags
[rlhs
[default_rule
]]);