home *** CD-ROM | disk | FTP | other *** search
- /* Find and resolve or report look-ahead conflicts for bison,
- Copyright (C) 1984 Bob Corbett and Free Software Foundation, Inc.
-
- BISON is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY. No author or distributor accepts responsibility to anyone
- for the consequences of using it or for whether it serves any
- particular purpose or works at all, unless he says so in writing.
- Refer to the BISON General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute BISON,
- but only under the conditions described in the BISON General Public
- License. A copy of this license is supposed to have been given to you
- along with BISON so you can know your rights and responsibilities. It
- should be in a file named COPYING. Among other things, the copyright
- notice and this notice must be preserved on all copies.
-
- In other words, you are welcome to use, share and improve this program.
- You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding! */
-
- #include <stdio.h>
- #include "machine.h"
- #include "new.h"
- #include "files.h"
- #include "gram.h"
- #include "state.h"
-
-
- extern char **tags;
- extern int tokensetsize;
- extern char *consistent;
- extern short *accessing_symbol;
- extern shifts **shift_table;
- extern unsigned *LA;
- extern short *LAruleno;
- extern short *lookaheads;
- extern int verboseflag;
-
- char any_conflicts;
- char *conflicts;
- errs **err_table;
- int expected_conflicts;
-
-
- static unsigned *shiftset;
- static unsigned *lookaheadset;
- static int src_total;
- static int rrc_total;
- static int src_count;
- static int rrc_count;
-
-
-
- initialize_conflicts()
- {
- register int i;
- /* register errs *sp; JF unused */
-
- conflicts = NEW2(nstates, char);
- shiftset = NEW2(tokensetsize, unsigned);
- lookaheadset = NEW2(tokensetsize, unsigned);
-
- err_table = NEW2(nstates, errs *);
-
- any_conflicts = 0;
-
- for (i = 0; i < nstates; i++)
- set_conflicts(i);
- }
-
-
-
- set_conflicts(state)
- int state;
- {
- register int i;
- register int k;
- register shifts *shiftp;
- register unsigned *fp2;
- register unsigned *fp3;
- register unsigned *fp4;
- register unsigned *fp1;
- register int symbol;
-
- if (consistent[state]) return;
-
- for (i = 0; i < tokensetsize; i++)
- lookaheadset[i] = 0;
-
- shiftp = shift_table[state];
- if (shiftp)
- {
- k = shiftp->nshifts;
- for (i = 0; i < k; i++)
- {
- symbol = accessing_symbol[shiftp->shifts[i]];
- if (ISVAR(symbol)) break;
- SETBIT(lookaheadset, symbol);
- }
- }
-
- k = lookaheads[state + 1];
- fp4 = lookaheadset + tokensetsize;
-
- /* loop over all rules which require lookahead in this state */
- /* first check for shift-reduce conflict, and try to resolve using precedence */
-
- for (i = lookaheads[state]; i < k; i++)
- if (rprec[LAruleno[i]])
- {
- fp1 = LA + i * tokensetsize;
- fp2 = fp1;
- fp3 = lookaheadset;
-
- while (fp3 < fp4)
- {
- if (*fp2++ & *fp3++)
- {
- resolve_sr_conflict(state, i);
- break;
- }
- }
- }
-
- /* loop over all rules which require lookahead in this state */
- /* Check for conflicts not resolved above. */
-
- for (i = lookaheads[state]; i < k; i++)
- {
- fp1 = LA + i * tokensetsize;
- fp2 = fp1;
- fp3 = lookaheadset;
-
- while (fp3 < fp4)
- {
- if (*fp2++ & *fp3++)
- {
- conflicts[state] = 1;
- any_conflicts = 1;
- }
- }
-
- fp2 = fp1;
- fp3 = lookaheadset;
-
- while (fp3 < fp4)
- *fp3++ |= *fp2++;
- }
- }
-
-
-
- /* Attempt to resolve shift-reduce conflict for one rule
- by means of precedence declarations.
- It has already been checked that the rule has a precedence.
- A conflict is resolved by modifying the shift or reduce tables
- so that there is no longer a conflict. */
-
- resolve_sr_conflict(state, lookaheadnum)
- int state;
- int lookaheadnum;
- {
- register int i;
- register int mask;
- register unsigned *fp1;
- register unsigned *fp2;
- register int redprec;
- errs *errp = (errs *) alloca (sizeof(errs) + ntokens * sizeof(short));
- short *errtokens = errp->errs;
-
- /* find the rule to reduce by to get precedence of reduction */
- redprec = rprec[LAruleno[lookaheadnum]];
-
- mask = 1;
- fp1 = LA + lookaheadnum * tokensetsize;
- fp2 = lookaheadset;
- for (i = 0; i < ntokens; i++)
- {
- if ((mask & *fp2 & *fp1) && sprec[i])
- /* shift-reduce conflict occurs for token number i and it has a precision.
- The precedence of shifting is that of token i. */
- {
- if (sprec[i] < redprec)
- {
- if (verboseflag) log_resolution(state, lookaheadnum, i, "reduce");
- *fp2 &= ~mask; /* flush the shift for this token */
- flush_shift(state, i);
- }
- else if (sprec[i] > redprec)
- {
- if (verboseflag) log_resolution(state, lookaheadnum, i, "shift");
- *fp1 &= ~mask; /* flush the reduce for this token */
- }
- else
- {
- /* Matching precedence levels.
- For left association, keep only the reduction.
- For right association, keep only the shift.
- For nonassociation, keep neither. */
-
- switch (sassoc[i])
- {
-
- case RIGHT_ASSOC:
- if (verboseflag) log_resolution(state, lookaheadnum, i, "shift");
- break;
-
- case LEFT_ASSOC:
- if (verboseflag) log_resolution(state, lookaheadnum, i, "reduce");
- break;
-
- case NON_ASSOC:
- if (verboseflag) log_resolution(state, lookaheadnum, i, "an error");
- break;
- }
-
- if (sassoc[i] != RIGHT_ASSOC)
- {
- *fp2 &= ~mask; /* flush the shift for this token */
- flush_shift(state, i);
- }
- if (sassoc[i] != LEFT_ASSOC)
- {
- *fp1 &= ~mask; /* flush the reduce for this token */
- }
- if (sassoc[i] ssoc[i] ssoc[i] ssoc[i] ssoc[i]