* src/closure.h: New file.

* src/closure.c: Formatting changes, topological sort over the
functions, use of closure.h.
(initialize_closure, finalize_closure):  Rename as...
(new_closure, free_closure): these.  Adjust dependencies.
* src/LR0.c: Formatting changes, topological sort, use of
cloture.h.
(initialize_states): Rename as...
(new_states): this.
* src/Makefile.am (noinst_HEADERS): Adjust.
This commit is contained in:
Akim Demaille
2000-09-21 10:17:59 +00:00
parent 2fa6973e6f
commit c29240e74b
12 changed files with 973 additions and 871 deletions

49
src/closure.h Normal file
View File

@@ -0,0 +1,49 @@
/* Subroutines for bison
Copyright (C) 1984, 1989, 2000 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
Bison is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Bison is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bison; see the file COPYING. If not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* Subroutines of file LR0.c. */
/* Allocates the itemset and ruleset vectors, and precomputes useful
data so that closure can be called. n is the number of elements to
allocate for itemset. */
void new_closure PARAMS ((int n));
/* Given a vector of item numbers ITEMS, of length N, set up ruleset
and itemset to indicate what rules could be run and which items
could be accepted when those items are the active ones.
ruleset contains a bit for each rule. closure sets the bits for
all rules which could potentially describe the next input to be
read.
itemset is a vector of item numbers; itemsetend points to just
beyond the end of the part of it that is significant. closure
places there the indices of all items which represent units of
input that could arrive next. */
void closure PARAMS ((short *items, int n));
/* Frees itemset, ruleset and internal data. */
void free_closure PARAMS ((void));

View File

@@ -36,19 +36,11 @@ extern short *LAruleno;
extern short *lookaheads;
extern int fixed_outfiles;
extern void initialize_conflicts PARAMS((void));
extern void conflict_log PARAMS((void));
extern void verbose_conflict_log PARAMS((void));
extern void print_reductions PARAMS((int));
extern void finalize_conflicts PARAMS((void));
static void set_conflicts PARAMS((int));
static void resolve_sr_conflict PARAMS((int, int));
static void flush_shift PARAMS((int, int));
static void log_resolution PARAMS((int, int, int, char *));
static void total_conflicts PARAMS((void));
static void count_sr_conflicts PARAMS((int));
static void count_rr_conflicts PARAMS((int));
extern void initialize_conflicts PARAMS ((void));
extern void conflict_log PARAMS ((void));
extern void verbose_conflict_log PARAMS ((void));
extern void print_reductions PARAMS ((int));
extern void finalize_conflicts PARAMS ((void));
char any_conflicts;
errs **err_table;
@@ -62,40 +54,164 @@ static int src_total;
static int rrc_total;
static int src_count;
static int rrc_count;
void
initialize_conflicts (void)
static inline void
log_resolution (int state, int LAno, int token, char *resolution)
{
register int i;
/* register errs *sp; JF unused */
if (verboseflag)
fprintf (foutput,
_("\
Conflict in state %d between rule %d and token %s resolved as %s.\n"),
state, LAruleno[LAno], tags[token], resolution);
}
conflicts = NEW2(nstates, char);
shiftset = NEW2(tokensetsize, unsigned);
lookaheadset = NEW2(tokensetsize, unsigned);
err_table = NEW2(nstates, errs *);
/*------------------------------------------------------------------.
| Turn off the shift recorded for the specified token in the |
| specified state. Used when we resolve a shift-reduce conflict in |
| favor of the reduction. |
`------------------------------------------------------------------*/
any_conflicts = 0;
static void
flush_shift (int state, int token)
{
shifts *shiftp;
int k, i;
for (i = 0; i < nstates; i++)
set_conflicts(i);
shiftp = shift_table[state];
if (shiftp)
{
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
if (shiftp->shifts[i]
&& token == accessing_symbol[shiftp->shifts[i]])
(shiftp->shifts[i]) = 0;
}
}
}
/*------------------------------------------------------------------.
| 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. |
`------------------------------------------------------------------*/
static void
resolve_sr_conflict (int state, int lookaheadnum)
{
int i;
int mask;
unsigned *fp1;
unsigned *fp2;
int redprec;
errs *errp = (errs *) xmalloc (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 precedence.
The precedence of shifting is that of token i. */
{
if (sprec[i] < redprec)
{
log_resolution (state, lookaheadnum, i, _("reduce"));
*fp2 &= ~mask; /* flush the shift for this token */
flush_shift (state, i);
}
else if (sprec[i] > redprec)
{
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:
log_resolution (state, lookaheadnum, i, _("shift"));
break;
case LEFT_ASSOC:
log_resolution (state, lookaheadnum, i, _("reduce"));
break;
case NON_ASSOC:
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] == NON_ASSOC)
{
/* Record an explicit error for this token. */
*errtokens++ = i;
}
}
}
mask <<= 1;
if (mask == 0)
{
mask = 1;
fp2++;
fp1++;
}
}
errp->nerrs = errtokens - errp->errs;
if (errp->nerrs)
{
/* Some tokens have been explicitly made errors. Allocate
a permanent errs structure for this state, to record them. */
i = (char *) errtokens - (char *) errp;
err_table[state] = (errs *) xmalloc ((unsigned int) i);
bcopy (errp, err_table[state], i);
}
else
err_table[state] = 0;
free (errp);
}
static void
set_conflicts (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;
int i;
int k;
shifts *shiftp;
unsigned *fp2;
unsigned *fp3;
unsigned *fp4;
unsigned *fp1;
int symbol;
if (consistent[state]) return;
if (consistent[state])
return;
for (i = 0; i < tokensetsize; i++)
lookaheadset[i] = 0;
@@ -107,17 +223,18 @@ set_conflicts (int state)
for (i = 0; i < k; i++)
{
symbol = accessing_symbol[shiftp->shifts[i]];
if (ISVAR(symbol)) break;
SETBIT(lookaheadset, symbol);
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 */
/* 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]])
{
@@ -129,15 +246,15 @@ set_conflicts (int state)
{
if (*fp2++ & *fp3++)
{
resolve_sr_conflict(state, i);
resolve_sr_conflict (state, i);
break;
}
}
}
/* loop over all rules which require lookahead in this state */
/* Check for conflicts not resolved above. */
/* 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;
@@ -161,267 +278,53 @@ set_conflicts (int state)
}
}
/* 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. */
static void
resolve_sr_conflict (int state, int lookaheadnum)
{
register int i;
register int mask;
register unsigned *fp1;
register unsigned *fp2;
register int redprec;
errs *errp = (errs *) xmalloc (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 precedence.
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] == NON_ASSOC)
{
/* Record an explicit error for this token. */
*errtokens++ = i;
}
}
}
mask <<= 1;
if (mask == 0)
{
mask = 1;
fp2++; fp1++;
}
}
errp->nerrs = errtokens - errp->errs;
if (errp->nerrs)
{
/* Some tokens have been explicitly made errors. Allocate
a permanent errs structure for this state, to record them. */
i = (char *) errtokens - (char *) errp;
err_table[state] = (errs *) xmalloc ((unsigned int)i);
bcopy (errp, err_table[state], i);
}
else
err_table[state] = 0;
free(errp);
}
/* turn off the shift recorded for the specified token in the specified state.
Used when we resolve a shift-reduce conflict in favor of the reduction. */
static void
flush_shift (int state, int token)
{
register shifts *shiftp;
register int k, i;
/* register unsigned symbol; JF unused */
shiftp = shift_table[state];
if (shiftp)
{
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
if (shiftp->shifts[i] && token == accessing_symbol[shiftp->shifts[i]])
(shiftp->shifts[i]) = 0;
}
}
}
static void
log_resolution (int state, int LAno, int token, char *resolution)
{
fprintf(foutput,
_("Conflict in state %d between rule %d and token %s resolved as %s.\n"),
state, LAruleno[LAno], tags[token], resolution);
}
void
conflict_log (void)
initialize_conflicts (void)
{
register int i;
int i;
/* errs *sp; JF unused */
src_total = 0;
rrc_total = 0;
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++)
{
if (conflicts[i])
{
count_sr_conflicts(i);
count_rr_conflicts(i);
src_total += src_count;
rrc_total += rrc_count;
}
}
total_conflicts();
set_conflicts (i);
}
void
verbose_conflict_log (void)
{
register int i;
src_total = 0;
rrc_total = 0;
for (i = 0; i < nstates; i++)
{
if (conflicts[i])
{
count_sr_conflicts(i);
count_rr_conflicts(i);
src_total += src_count;
rrc_total += rrc_count;
fprintf(foutput, _("State %d contains"), i);
if (src_count == 1)
fprintf(foutput, _(" 1 shift/reduce conflict"));
else if (src_count > 1)
fprintf(foutput, _(" %d shift/reduce conflicts"), src_count);
if (src_count > 0 && rrc_count > 0)
fprintf(foutput, _(" and"));
if (rrc_count == 1)
fprintf(foutput, _(" 1 reduce/reduce conflict"));
else if (rrc_count > 1)
fprintf(foutput, _(" %d reduce/reduce conflicts"), rrc_count);
putc('.', foutput);
putc('\n', foutput);
}
}
total_conflicts();
}
static void
total_conflicts (void)
{
if (src_total == expected_conflicts && rrc_total == 0)
return;
if (fixed_outfiles)
{
/* If invoked under the name `yacc', use the output format
specified by POSIX. */
fprintf(stderr, _("conflicts: "));
if (src_total > 0)
fprintf(stderr, _(" %d shift/reduce"), src_total);
if (src_total > 0 && rrc_total > 0)
fprintf(stderr, ",");
if (rrc_total > 0)
fprintf(stderr, _(" %d reduce/reduce"), rrc_total);
putc('\n', stderr);
}
else
{
fprintf(stderr, _("%s contains"), infile);
if (src_total == 1)
fprintf(stderr, _(" 1 shift/reduce conflict"));
else if (src_total > 1)
fprintf(stderr, _(" %d shift/reduce conflicts"), src_total);
if (src_total > 0 && rrc_total > 0)
fprintf(stderr, _(" and"));
if (rrc_total == 1)
fprintf(stderr, _(" 1 reduce/reduce conflict"));
else if (rrc_total > 1)
fprintf(stderr, _(" %d reduce/reduce conflicts"), rrc_total);
putc('.', stderr);
putc('\n', stderr);
}
}
/*---------------------------------------------.
| Count the number of shift/reduce conflicts. |
`---------------------------------------------*/
static void
count_sr_conflicts (int state)
{
register int i;
register int k;
register int mask;
register shifts *shiftp;
register unsigned *fp1;
register unsigned *fp2;
register unsigned *fp3;
register int symbol;
int i;
int k;
int mask;
shifts *shiftp;
unsigned *fp1;
unsigned *fp2;
unsigned *fp3;
int symbol;
src_count = 0;
shiftp = shift_table[state];
if (!shiftp) return;
if (!shiftp)
return;
for (i = 0; i < tokensetsize; i++)
{
@@ -432,10 +335,12 @@ count_sr_conflicts (int state)
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
if (! shiftp->shifts[i]) continue;
if (!shiftp->shifts[i])
continue;
symbol = accessing_symbol[shiftp->shifts[i]];
if (ISVAR(symbol)) break;
SETBIT(shiftset, symbol);
if (ISVAR (symbol))
break;
SETBIT (shiftset, symbol);
}
k = lookaheads[state + 1];
@@ -473,24 +378,29 @@ count_sr_conflicts (int state)
}
/*----------------------------------------------.
| Count the number of reduce/reduce conflicts. |
`----------------------------------------------*/
static void
count_rr_conflicts (int state)
{
register int i;
register int j;
register int count;
register unsigned mask;
register unsigned *baseword;
register unsigned *wordp;
register int m;
register int n;
int i;
int j;
int count;
unsigned mask;
unsigned *baseword;
unsigned *wordp;
int m;
int n;
rrc_count = 0;
m = lookaheads[state];
n = lookaheads[state + 1];
if (n - m < 2) return;
if (n - m < 2)
return;
mask = 1;
baseword = LA + m * tokensetsize;
@@ -507,7 +417,8 @@ count_rr_conflicts (int state)
wordp += tokensetsize;
}
if (count >= 2) rrc_count++;
if (count >= 2)
rrc_count++;
mask <<= 1;
if (mask == 0)
@@ -518,28 +429,145 @@ count_rr_conflicts (int state)
}
}
/*------------------------------------.
| Give a report about the conflicts. |
`------------------------------------*/
static void
total_conflicts (void)
{
if (src_total == expected_conflicts && rrc_total == 0)
return;
if (fixed_outfiles)
{
/* If invoked under the name `yacc', use the output format
specified by POSIX. */
fprintf (stderr, _("conflicts: "));
if (src_total > 0)
fprintf (stderr, _(" %d shift/reduce"), src_total);
if (src_total > 0 && rrc_total > 0)
fprintf (stderr, ",");
if (rrc_total > 0)
fprintf (stderr, _(" %d reduce/reduce"), rrc_total);
putc ('\n', stderr);
}
else
{
fprintf (stderr, _("%s contains"), infile);
if (src_total == 1)
fprintf (stderr, _(" 1 shift/reduce conflict"));
else if (src_total > 1)
fprintf (stderr, _(" %d shift/reduce conflicts"), src_total);
if (src_total > 0 && rrc_total > 0)
fprintf (stderr, _(" and"));
if (rrc_total == 1)
fprintf (stderr, _(" 1 reduce/reduce conflict"));
else if (rrc_total > 1)
fprintf (stderr, _(" %d reduce/reduce conflicts"), rrc_total);
putc ('.', stderr);
putc ('\n', stderr);
}
}
/*---------------------------------------------.
| Compute and give a report on the conflicts. |
`---------------------------------------------*/
void
conflict_log (void)
{
int i;
src_total = 0;
rrc_total = 0;
for (i = 0; i < nstates; i++)
{
if (conflicts[i])
{
count_sr_conflicts (i);
count_rr_conflicts (i);
src_total += src_count;
rrc_total += rrc_count;
}
}
total_conflicts ();
}
void
verbose_conflict_log (void)
{
int i;
src_total = 0;
rrc_total = 0;
for (i = 0; i < nstates; i++)
{
if (conflicts[i])
{
count_sr_conflicts (i);
count_rr_conflicts (i);
src_total += src_count;
rrc_total += rrc_count;
fprintf (foutput, _("State %d contains"), i);
if (src_count == 1)
fprintf (foutput, _(" 1 shift/reduce conflict"));
else if (src_count > 1)
fprintf (foutput, _(" %d shift/reduce conflicts"), src_count);
if (src_count > 0 && rrc_count > 0)
fprintf (foutput, _(" and"));
if (rrc_count == 1)
fprintf (foutput, _(" 1 reduce/reduce conflict"));
else if (rrc_count > 1)
fprintf (foutput, _(" %d reduce/reduce conflicts"), rrc_count);
putc ('.', foutput);
putc ('\n', foutput);
}
}
total_conflicts ();
}
void
print_reductions (int state)
{
register int i;
register int j;
register int k;
register unsigned *fp1;
register unsigned *fp2;
register unsigned *fp3;
register unsigned *fp4;
register int rule;
register int symbol;
register unsigned mask;
register int m;
register int n;
register int default_LA;
register int default_rule = 0;
register int cmax;
register int count;
register shifts *shiftp;
register errs *errp;
int i;
int j;
int k;
unsigned *fp1;
unsigned *fp2;
unsigned *fp3;
unsigned *fp4;
int rule;
int symbol;
unsigned mask;
int m;
int n;
int default_LA;
int default_rule = 0;
int cmax;
int count;
shifts *shiftp;
errs *errp;
int nodefault = 0;
for (i = 0; i < tokensetsize; i++)
@@ -551,13 +579,16 @@ print_reductions (int state)
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
if (! shiftp->shifts[i]) continue;
if (!shiftp->shifts[i])
continue;
symbol = accessing_symbol[shiftp->shifts[i]];
if (ISVAR(symbol)) break;
if (ISVAR (symbol))
break;
/* if this state has a shift for the error token,
don't use a default rule. */
if (symbol == error_token_number) nodefault = 1;
SETBIT(shiftset, symbol);
if (symbol == error_token_number)
nodefault = 1;
SETBIT (shiftset, symbol);
}
}
@@ -567,16 +598,17 @@ print_reductions (int state)
k = errp->nerrs;
for (i = 0; i < k; i++)
{
if (! errp->errs[i]) continue;
if (!errp->errs[i])
continue;
symbol = errp->errs[i];
SETBIT(shiftset, symbol);
SETBIT (shiftset, symbol);
}
}
m = lookaheads[state];
n = lookaheads[state + 1];
if (n - m == 1 && ! nodefault)
if (n - m == 1 && !nodefault)
{
default_rule = LAruleno[m];
@@ -594,8 +626,8 @@ print_reductions (int state)
for (i = 0; i < ntokens; i++)
{
if (mask & *fp3)
fprintf(foutput, _(" %-4s\t[reduce using rule %d (%s)]\n"),
tags[i], default_rule, tags[rlhs[default_rule]]);
fprintf (foutput, _(" %-4s\t[reduce using rule %d (%s)]\n"),
tags[i], default_rule, tags[rlhs[default_rule]]);
mask <<= 1;
if (mask == 0)
@@ -605,8 +637,8 @@ print_reductions (int state)
}
}
fprintf(foutput, _(" $default\treduce using rule %d (%s)\n\n"),
default_rule, tags[rlhs[default_rule]]);
fprintf (foutput, _(" $default\treduce using rule %d (%s)\n\n"),
default_rule, tags[rlhs[default_rule]]);
}
else if (n - m >= 1)
{
@@ -614,7 +646,7 @@ print_reductions (int state)
default_LA = -1;
fp4 = lookaheadset + tokensetsize;
if (! nodefault)
if (!nodefault)
for (i = m; i < n; i++)
{
fp1 = LA + i * tokensetsize;
@@ -655,19 +687,21 @@ print_reductions (int state)
}
for (i = 0; i < tokensetsize; i++)
shiftset[i] = 0;
shiftset[i] = 0;
if (shiftp)
{
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
if (! shiftp->shifts[i]) continue;
if (!shiftp->shifts[i])
continue;
symbol = accessing_symbol[shiftp->shifts[i]];
if (ISVAR(symbol)) break;
SETBIT(shiftset, symbol);
if (ISVAR (symbol))
break;
SETBIT (shiftset, symbol);
}
}
}
mask = 1;
fp1 = LA + m * tokensetsize;
@@ -691,10 +725,12 @@ print_reductions (int state)
if (j != default_LA)
{
rule = LAruleno[j];
fprintf(foutput, _(" %-4s\treduce using rule %d (%s)\n"),
tags[i], rule, tags[rlhs[rule]]);
fprintf (foutput,
_(" %-4s\treduce using rule %d (%s)\n"),
tags[i], rule, tags[rlhs[rule]]);
}
else defaulted = 1;
else
defaulted = 1;
count++;
}
@@ -703,13 +739,15 @@ print_reductions (int state)
if (defaulted)
{
rule = LAruleno[default_LA];
fprintf(foutput, _(" %-4s\treduce using rule %d (%s)\n"),
tags[i], rule, tags[rlhs[rule]]);
fprintf (foutput,
_(" %-4s\treduce using rule %d (%s)\n"),
tags[i], rule, tags[rlhs[rule]]);
defaulted = 0;
}
rule = LAruleno[j];
fprintf(foutput, _(" %-4s\t[reduce using rule %d (%s)]\n"),
tags[i], rule, tags[rlhs[rule]]);
fprintf (foutput,
_(" %-4s\t[reduce using rule %d (%s)]\n"),
tags[i], rule, tags[rlhs[rule]]);
}
}
@@ -721,7 +759,7 @@ print_reductions (int state)
{
mask = 1;
/* We tried incrementing just fp1, and just fp2; both seem wrong.
It seems necessary to increment both in sync. */
It seems necessary to increment both in sync. */
fp1++;
fp2++;
}
@@ -729,11 +767,11 @@ print_reductions (int state)
if (default_LA >= 0)
{
fprintf(foutput, _(" $default\treduce using rule %d (%s)\n"),
default_rule, tags[rlhs[default_rule]]);
fprintf (foutput, _(" $default\treduce using rule %d (%s)\n"),
default_rule, tags[rlhs[default_rule]]);
}
putc('\n', foutput);
putc ('\n', foutput);
}
}
@@ -741,7 +779,7 @@ print_reductions (int state)
void
finalize_conflicts (void)
{
FREE(conflicts);
FREE(shiftset);
FREE(lookaheadset);
FREE (conflicts);
FREE (shiftset);
FREE (lookaheadset);
}

View File

@@ -1,22 +1,22 @@
/* Print information on generated parser, for bison,
Copyright (C) 1984, 1986, 1989 Free Software Foundation, Inc.
Copyright (C) 1984, 1986, 1989, 2000 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This file is part of Bison, the GNU Compiler Compiler.
Bison is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Bison is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Bison is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Bison is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bison; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
You should have received a copy of the GNU General Public License
along with Bison; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "system.h"
@@ -38,54 +38,50 @@ extern char any_conflicts;
extern char *conflicts;
extern int final_state;
extern void conflict_log PARAMS((void));
extern void verbose_conflict_log PARAMS((void));
extern void print_reductions PARAMS((int));
extern void conflict_log PARAMS ((void));
extern void verbose_conflict_log PARAMS ((void));
extern void print_reductions PARAMS ((int));
extern void terse PARAMS((void));
extern void verbose PARAMS((void));
extern void terse PARAMS ((void));
extern void verbose PARAMS ((void));
#if 0 /* XXX currently unused. */
static void print_token PARAMS((int, int));
#if 0 /* XXX currently unused. */
static void print_token PARAMS ((int, int));
#endif
static void print_state PARAMS((int));
static void print_core PARAMS((int));
static void print_actions PARAMS((int));
static void print_grammar PARAMS((void));
static void print_state PARAMS ((int));
static void print_core PARAMS ((int));
static void print_actions PARAMS ((int));
static void print_grammar PARAMS ((void));
void
terse (void)
{
if (any_conflicts)
{
conflict_log();
}
conflict_log ();
}
void
verbose (void)
{
register int i;
int i;
if (any_conflicts)
verbose_conflict_log();
verbose_conflict_log ();
print_grammar();
print_grammar ();
for (i = 0; i < nstates; i++)
{
print_state(i);
}
print_state (i);
}
#if 0 /* XXX currently unused. */
#if 0 /* XXX currently unused. */
static void
print_token (int extnum, int token)
{
fprintf(foutput, _(" type %d is %s\n"), extnum, tags[token]);
fprintf (foutput, _(" type %d is %s\n"), extnum, tags[token]);
}
#endif
@@ -93,26 +89,27 @@ print_token (int extnum, int token)
static void
print_state (int state)
{
fprintf(foutput, _("\n\nstate %d\n\n"), state);
print_core(state);
print_actions(state);
fprintf (foutput, _("\n\nstate %d\n\n"), state);
print_core (state);
print_actions (state);
}
static void
print_core (int state)
{
register int i;
register int k;
register int rule;
register core *statep;
register short *sp;
register short *sp1;
int i;
int k;
int rule;
core *statep;
short *sp;
short *sp1;
statep = state_table[state];
k = statep->nitems;
if (k == 0) return;
if (k == 0)
return;
for (i = 0; i < k; i++)
{
@@ -122,40 +119,40 @@ print_core (int state)
sp++;
rule = -(*sp);
fprintf(foutput, " %s -> ", tags[rlhs[rule]]);
fprintf (foutput, " %s -> ", tags[rlhs[rule]]);
for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
{
fprintf(foutput, "%s ", tags[*sp]);
fprintf (foutput, "%s ", tags[*sp]);
}
putc('.', foutput);
putc ('.', foutput);
while (*sp > 0)
{
fprintf(foutput, " %s", tags[*sp]);
fprintf (foutput, " %s", tags[*sp]);
sp++;
}
fprintf (foutput, _(" (rule %d)"), rule);
putc('\n', foutput);
putc ('\n', foutput);
}
putc('\n', foutput);
putc ('\n', foutput);
}
static void
print_actions (int state)
{
register int i;
register int k;
register int state1;
register int symbol;
register shifts *shiftp;
register errs *errp;
register reductions *redp;
register int rule;
int i;
int k;
int state1;
int symbol;
shifts *shiftp;
errs *errp;
reductions *redp;
int rule;
shiftp = shift_table[state];
redp = reduction_table[state];
@@ -164,9 +161,9 @@ print_actions (int state)
if (!shiftp && !redp)
{
if (final_state == state)
fprintf(foutput, _(" $default\taccept\n"));
fprintf (foutput, _(" $default\taccept\n"));
else
fprintf(foutput, _(" NO ACTIONS\n"));
fprintf (foutput, _(" NO ACTIONS\n"));
return;
}
@@ -176,20 +173,22 @@ print_actions (int state)
for (i = 0; i < k; i++)
{
if (! shiftp->shifts[i]) continue;
if (!shiftp->shifts[i])
continue;
state1 = shiftp->shifts[i];
symbol = accessing_symbol[state1];
/* The following line used to be turned off. */
if (ISVAR(symbol)) break;
if (symbol==0) /* I.e. strcmp(tags[symbol],"$")==0 */
fprintf(foutput, _(" $ \tgo to state %d\n"), state1);
else
fprintf(foutput, _(" %-4s\tshift, and go to state %d\n"),
tags[symbol], state1);
if (ISVAR (symbol))
break;
if (symbol == 0) /* I.e. strcmp(tags[symbol],"$")==0 */
fprintf (foutput, _(" $ \tgo to state %d\n"), state1);
else
fprintf (foutput, _(" %-4s\tshift, and go to state %d\n"),
tags[symbol], state1);
}
if (i > 0)
putc('\n', foutput);
putc ('\n', foutput);
}
else
{
@@ -205,38 +204,42 @@ print_actions (int state)
for (j = 0; j < nerrs; j++)
{
if (! errp->errs[j]) continue;
if (!errp->errs[j])
continue;
symbol = errp->errs[j];
fprintf(foutput, _(" %-4s\terror (nonassociative)\n"), tags[symbol]);
fprintf (foutput, _(" %-4s\terror (nonassociative)\n"),
tags[symbol]);
}
if (j > 0)
putc('\n', foutput);
putc ('\n', foutput);
}
if (consistent[state] && redp)
{
rule = redp->rules[0];
symbol = rlhs[rule];
fprintf(foutput, _(" $default\treduce using rule %d (%s)\n\n"),
rule, tags[symbol]);
fprintf (foutput, _(" $default\treduce using rule %d (%s)\n\n"),
rule, tags[symbol]);
}
else if (redp)
{
print_reductions(state);
print_reductions (state);
}
if (i < k)
{
for (; i < k; i++)
{
if (! shiftp->shifts[i]) continue;
if (!shiftp->shifts[i])
continue;
state1 = shiftp->shifts[i];
symbol = accessing_symbol[state1];
fprintf(foutput, _(" %-4s\tgo to state %d\n"), tags[symbol], state1);
fprintf (foutput, _(" %-4s\tgo to state %d\n"), tags[symbol],
state1);
}
putc('\n', foutput);
putc ('\n', foutput);
}
}
@@ -253,29 +256,29 @@ static void
print_grammar (void)
{
int i, j;
short* rule;
short *rule;
char buffer[90];
int column = 0;
/* rule # : LHS -> RHS */
fputs(_("\nGrammar\n"), foutput);
fputs (_("\nGrammar\n"), foutput);
for (i = 1; i <= nrules; i++)
/* Don't print rules disabled in reduce_grammar_tables. */
if (rlhs[i] >= 0)
{
fprintf(foutput, _("rule %-4d %s ->"), i, tags[rlhs[i]]);
fprintf (foutput, _("rule %-4d %s ->"), i, tags[rlhs[i]]);
rule = &ritem[rrhs[i]];
if (*rule > 0)
while (*rule > 0)
fprintf(foutput, " %s", tags[*rule++]);
fprintf (foutput, " %s", tags[*rule++]);
else
fputs (_(" /* empty */"), foutput);
putc('\n', foutput);
putc ('\n', foutput);
}
/* TERMINAL (type #) : rule #s terminal is on RHS */
fputs(_("\nTerminals, with rules where they appear\n\n"), foutput);
fprintf(foutput, "%s (-1)\n", tags[0]);
fputs (_("\nTerminals, with rules where they appear\n\n"), foutput);
fprintf (foutput, "%s (-1)\n", tags[0]);
if (translations)
{
for (i = 0; i <= max_user_token_number; i++)
@@ -283,7 +286,7 @@ print_grammar (void)
{
buffer[0] = 0;
column = strlen (tags[token_translations[i]]);
fprintf(foutput, "%s", tags[token_translations[i]]);
fprintf (foutput, "%s", tags[token_translations[i]]);
END_TEST (50);
sprintf (buffer, " (%d)", i);
@@ -293,7 +296,7 @@ print_grammar (void)
if (*rule == token_translations[i])
{
END_TEST (65);
sprintf (buffer + strlen(buffer), " %d", j);
sprintf (buffer + strlen (buffer), " %d", j);
break;
}
}
@@ -305,7 +308,7 @@ print_grammar (void)
{
buffer[0] = 0;
column = strlen (tags[i]);
fprintf(foutput, "%s", tags[i]);
fprintf (foutput, "%s", tags[i]);
END_TEST (50);
sprintf (buffer, " (%d)", i);
@@ -315,14 +318,14 @@ print_grammar (void)
if (*rule == i)
{
END_TEST (65);
sprintf (buffer + strlen(buffer), " %d", j);
sprintf (buffer + strlen (buffer), " %d", j);
break;
}
}
fprintf (foutput, "%s\n", buffer);
}
fputs(_("\nNonterminals, with rules where they appear\n\n"), foutput);
fputs (_("\nNonterminals, with rules where they appear\n\n"), foutput);
for (i = ntokens; i <= nsyms - 1; i++)
{
int left_count = 0, right_count = 0;
@@ -340,7 +343,7 @@ print_grammar (void)
}
buffer[0] = 0;
fprintf(foutput, "%s", tags[i]);
fprintf (foutput, "%s", tags[i]);
column = strlen (tags[i]);
sprintf (buffer, " (%d)", i);
END_TEST (0);
@@ -348,29 +351,29 @@ print_grammar (void)
if (left_count > 0)
{
END_TEST (50);
sprintf (buffer + strlen(buffer), _(" on left:"));
sprintf (buffer + strlen (buffer), _(" on left:"));
for (j = 1; j <= nrules; j++)
{
END_TEST (65);
if (rlhs[j] == i)
sprintf (buffer + strlen(buffer), " %d", j);
sprintf (buffer + strlen (buffer), " %d", j);
}
}
if (right_count > 0)
{
if (left_count > 0)
sprintf (buffer + strlen(buffer), ",");
sprintf (buffer + strlen (buffer), ",");
END_TEST (50);
sprintf (buffer + strlen(buffer), _(" on right:"));
sprintf (buffer + strlen (buffer), _(" on right:"));
for (j = 1; j <= nrules; j++)
{
for (rule = &ritem[rrhs[j]]; *rule > 0; rule++)
if (*rule == i)
{
END_TEST (65);
sprintf (buffer + strlen(buffer), " %d", j);
sprintf (buffer + strlen (buffer), " %d", j);
break;
}
}