]>
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 void initialize_conflicts
PARAMS((void));
42 void set_conflicts
PARAMS((int));
43 void resolve_sr_conflict
PARAMS((int, int));
44 void flush_shift
PARAMS((int, int));
45 void log_resolution
PARAMS((int, int, int, char *));
46 void conflict_log
PARAMS((void));
47 void verbose_conflict_log
PARAMS((void));
48 void total_conflicts
PARAMS((void));
49 void count_sr_conflicts
PARAMS((int));
50 void count_rr_conflicts
PARAMS((int));
51 void print_reductions
PARAMS((int));
52 void finalize_conflicts
PARAMS((void));
57 int expected_conflicts
;
60 static unsigned *shiftset
;
61 static unsigned *lookaheadset
;
69 initialize_conflicts (void)
72 /* register errs *sp; JF unused */
74 conflicts
= NEW2(nstates
, char);
75 shiftset
= NEW2(tokensetsize
, unsigned);
76 lookaheadset
= NEW2(tokensetsize
, unsigned);
78 err_table
= NEW2(nstates
, errs
*);
82 for (i
= 0; i
< nstates
; i
++)
88 set_conflicts (int state
)
92 register shifts
*shiftp
;
93 register unsigned *fp2
;
94 register unsigned *fp3
;
95 register unsigned *fp4
;
96 register unsigned *fp1
;
99 if (consistent
[state
]) return;
101 for (i
= 0; i
< tokensetsize
; i
++)
104 shiftp
= shift_table
[state
];
108 for (i
= 0; i
< k
; i
++)
110 symbol
= accessing_symbol
[shiftp
->shifts
[i
]];
111 if (ISVAR(symbol
)) break;
112 SETBIT(lookaheadset
, symbol
);
116 k
= lookaheads
[state
+ 1];
117 fp4
= lookaheadset
+ tokensetsize
;
119 /* loop over all rules which require lookahead in this state */
120 /* first check for shift-reduce conflict, and try to resolve using precedence */
122 for (i
= lookaheads
[state
]; i
< k
; i
++)
123 if (rprec
[LAruleno
[i
]])
125 fp1
= LA
+ i
* tokensetsize
;
133 resolve_sr_conflict(state
, i
);
139 /* loop over all rules which require lookahead in this state */
140 /* Check for conflicts not resolved above. */
142 for (i
= lookaheads
[state
]; i
< k
; i
++)
144 fp1
= LA
+ i
* tokensetsize
;
152 conflicts
[state
] = 1;
167 /* Attempt to resolve shift-reduce conflict for one rule
168 by means of precedence declarations.
169 It has already been checked that the rule has a precedence.
170 A conflict is resolved by modifying the shift or reduce tables
171 so that there is no longer a conflict. */
174 resolve_sr_conflict (int state
, int lookaheadnum
)
178 register unsigned *fp1
;
179 register unsigned *fp2
;
180 register int redprec
;
181 errs
*errp
= (errs
*) xmalloc (sizeof(errs
) + ntokens
* sizeof(short));
182 short *errtokens
= errp
->errs
;
184 /* find the rule to reduce by to get precedence of reduction */
185 redprec
= rprec
[LAruleno
[lookaheadnum
]];
188 fp1
= LA
+ lookaheadnum
* tokensetsize
;
190 for (i
= 0; i
< ntokens
; i
++)
192 if ((mask
& *fp2
& *fp1
) && sprec
[i
])
193 /* Shift-reduce conflict occurs for token number i
194 and it has a precedence.
195 The precedence of shifting is that of token i. */
197 if (sprec
[i
] < redprec
)
199 if (verboseflag
) log_resolution(state
, lookaheadnum
, i
, _("reduce"));
200 *fp2
&= ~mask
; /* flush the shift for this token */
201 flush_shift(state
, i
);
203 else if (sprec
[i
] > redprec
)
205 if (verboseflag
) log_resolution(state
, lookaheadnum
, i
, _("shift"));
206 *fp1
&= ~mask
; /* flush the reduce for this token */
210 /* Matching precedence levels.
211 For left association, keep only the reduction.
212 For right association, keep only the shift.
213 For nonassociation, keep neither. */
219 if (verboseflag
) log_resolution(state
, lookaheadnum
, i
, _("shift"));
223 if (verboseflag
) log_resolution(state
, lookaheadnum
, i
, _("reduce"));
227 if (verboseflag
) log_resolution(state
, lookaheadnum
, i
, _("an error"));
231 if (sassoc
[i
] != RIGHT_ASSOC
)
233 *fp2
&= ~mask
; /* flush the shift for this token */
234 flush_shift(state
, i
);
236 if (sassoc
[i
] != LEFT_ASSOC
)
238 *fp1
&= ~mask
; /* flush the reduce for this token */
240 if (sassoc
[i
] == NON_ASSOC
)
242 /* Record an explicit error for this token. */
255 errp
->nerrs
= errtokens
- errp
->errs
;
258 /* Some tokens have been explicitly made errors. Allocate
259 a permanent errs structure for this state, to record them. */
260 i
= (char *) errtokens
- (char *) errp
;
261 err_table
[state
] = (errs
*) xmalloc ((unsigned int)i
);
262 bcopy (errp
, err_table
[state
], i
);
265 err_table
[state
] = 0;
271 /* turn off the shift recorded for the specified token in the specified state.
272 Used when we resolve a shift-reduce conflict in favor of the reduction. */
275 flush_shift (int state
, int token
)
277 register shifts
*shiftp
;
279 /* register unsigned symbol; JF unused */
281 shiftp
= shift_table
[state
];
286 for (i
= 0; i
< k
; i
++)
288 if (shiftp
->shifts
[i
] && token
== accessing_symbol
[shiftp
->shifts
[i
]])
289 (shiftp
->shifts
[i
]) = 0;
296 log_resolution (int state
, int LAno
, int token
, char *resolution
)
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 (void)
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
);
369 total_conflicts (void)
371 if (src_total
== expected_conflicts
&& rrc_total
== 0)
376 /* If invoked under the name `yacc', use the output format
377 specified by POSIX. */
378 fprintf(stderr
, _("conflicts: "));
380 fprintf(stderr
, _(" %d shift/reduce"), src_total
);
381 if (src_total
> 0 && rrc_total
> 0)
382 fprintf(stderr
, ",");
384 fprintf(stderr
, _(" %d reduce/reduce"), rrc_total
);
389 fprintf(stderr
, _("%s contains"), infile
);
392 fprintf(stderr
, _(" 1 shift/reduce conflict"));
393 else if (src_total
> 1)
394 fprintf(stderr
, _(" %d shift/reduce conflicts"), src_total
);
396 if (src_total
> 0 && rrc_total
> 0)
397 fprintf(stderr
, _(" and"));
400 fprintf(stderr
, _(" 1 reduce/reduce conflict"));
401 else if (rrc_total
> 1)
402 fprintf(stderr
, _(" %d reduce/reduce conflicts"), rrc_total
);
411 count_sr_conflicts (int state
)
416 register shifts
*shiftp
;
417 register unsigned *fp1
;
418 register unsigned *fp2
;
419 register unsigned *fp3
;
424 shiftp
= shift_table
[state
];
427 for (i
= 0; i
< tokensetsize
; i
++)
434 for (i
= 0; i
< k
; i
++)
436 if (! shiftp
->shifts
[i
]) continue;
437 symbol
= accessing_symbol
[shiftp
->shifts
[i
]];
438 if (ISVAR(symbol
)) break;
439 SETBIT(shiftset
, symbol
);
442 k
= lookaheads
[state
+ 1];
443 fp3
= lookaheadset
+ tokensetsize
;
445 for (i
= lookaheads
[state
]; i
< k
; i
++)
447 fp1
= LA
+ i
* tokensetsize
;
462 for (i
= 0; i
< ntokens
; i
++)
478 count_rr_conflicts (int state
)
483 register unsigned mask
;
484 register unsigned *baseword
;
485 register unsigned *wordp
;
491 m
= lookaheads
[state
];
492 n
= lookaheads
[state
+ 1];
494 if (n
- m
< 2) return;
497 baseword
= LA
+ m
* tokensetsize
;
498 for (i
= 0; i
< ntokens
; i
++)
503 for (j
= m
; j
< n
; j
++)
508 wordp
+= tokensetsize
;
511 if (count
>= 2) rrc_count
++;
524 print_reductions (int state
)
529 register unsigned *fp1
;
530 register unsigned *fp2
;
531 register unsigned *fp3
;
532 register unsigned *fp4
;
535 register unsigned mask
;
538 register int default_LA
;
539 register int default_rule
;
542 register shifts
*shiftp
;
546 for (i
= 0; i
< tokensetsize
; i
++)
549 shiftp
= shift_table
[state
];
553 for (i
= 0; i
< k
; i
++)
555 if (! shiftp
->shifts
[i
]) continue;
556 symbol
= accessing_symbol
[shiftp
->shifts
[i
]];
557 if (ISVAR(symbol
)) break;
558 /* if this state has a shift for the error token,
559 don't use a default rule. */
560 if (symbol
== error_token_number
) nodefault
= 1;
561 SETBIT(shiftset
, symbol
);
565 errp
= err_table
[state
];
569 for (i
= 0; i
< k
; i
++)
571 if (! errp
->errs
[i
]) continue;
572 symbol
= errp
->errs
[i
];
573 SETBIT(shiftset
, symbol
);
577 m
= lookaheads
[state
];
578 n
= lookaheads
[state
+ 1];
580 if (n
- m
== 1 && ! nodefault
)
582 default_rule
= LAruleno
[m
];
584 fp1
= LA
+ m
* tokensetsize
;
587 fp4
= lookaheadset
+ tokensetsize
;
590 *fp3
++ = *fp1
++ & *fp2
++;
595 for (i
= 0; i
< ntokens
; i
++)
598 fprintf(foutput
, _(" %-4s\t[reduce using rule %d (%s)]\n"),
599 tags
[i
], default_rule
, tags
[rlhs
[default_rule
]]);
609 fprintf(foutput
, _(" $default\treduce using rule %d (%s)\n\n"),
610 default_rule
, tags
[rlhs
[default_rule
]]);
616 fp4
= lookaheadset
+ tokensetsize
;
619 for (i
= m
; i
< n
; i
++)
621 fp1
= LA
+ i
* tokensetsize
;
626 *fp3
++ = *fp1
++ & (~(*fp2
++));
631 for (j
= 0; j
< ntokens
; j
++)
648 default_rule
= LAruleno
[i
];
658 for (i
= 0; i
< tokensetsize
; i
++)
664 for (i
= 0; i
< k
; i
++)
666 if (! shiftp
->shifts
[i
]) continue;
667 symbol
= accessing_symbol
[shiftp
->shifts
[i
]];
668 if (ISVAR(symbol
)) break;
669 SETBIT(shiftset
, symbol
);
674 fp1
= LA
+ m
* tokensetsize
;
676 for (i
= 0; i
< ntokens
; i
++)
686 for (j
= m
; j
< n
; j
++)
695 fprintf(foutput
, _(" %-4s\treduce using rule %d (%s)\n"),
696 tags
[i
], rule
, tags
[rlhs
[rule
]]);
706 rule
= LAruleno
[default_LA
];
707 fprintf(foutput
, _(" %-4s\treduce using rule %d (%s)\n"),
708 tags
[i
], rule
, tags
[rlhs
[rule
]]);
712 fprintf(foutput
, _(" %-4s\t[reduce using rule %d (%s)]\n"),
713 tags
[i
], rule
, tags
[rlhs
[rule
]]);
724 /* We tried incrementing just fp1, and just fp2; both seem wrong.
725 It seems necessary to increment both in sync. */
733 fprintf(foutput
, _(" $default\treduce using rule %d (%s)\n"),
734 default_rule
, tags
[rlhs
[default_rule
]]);
743 finalize_conflicts (void)