diff options
Diffstat (limited to 'tools/bison++/print.cc')
-rw-r--r-- | tools/bison++/print.cc | 369 |
1 files changed, 369 insertions, 0 deletions
diff --git a/tools/bison++/print.cc b/tools/bison++/print.cc new file mode 100644 index 000000000..ef045195a --- /dev/null +++ b/tools/bison++/print.cc @@ -0,0 +1,369 @@ +/* Print information on generated parser, for bison, + Copyright (C) 1984, 1986, 1989 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +#include <stdio.h> +#include "system.h" +#include "machine.h" +#include "new.h" +#include "files.h" +#include "gram.h" +#include "state.h" + + +extern char **tags; +extern int nstates; +extern short *accessing_symbol; +extern core **state_table; +extern shifts **shift_table; +extern errs **err_table; +extern reductions **reduction_table; +extern char *consistent; +extern char any_conflicts; +extern char *conflicts; +extern int final_state; + +extern void conflict_log(); +extern void verbose_conflict_log(); +extern void print_reductions(int); + +void print_token(int,int); +void print_state(int); +void print_core(int); +void print_actions(int); +void print_grammar(); + +void +terse() +{ + if (any_conflicts) + { + conflict_log(); + } +} + + +void +verbose() +{ + register int i; + + if (any_conflicts) + verbose_conflict_log(); + + print_grammar(); + + for (i = 0; i < nstates; i++) + { + print_state(i); + } +} + + +void +print_token(int extnum, int token) +{ + fprintf(foutput, " type %d is %s\n", extnum, tags[token]); +} + + +void +print_state(int state) +{ + fprintf(foutput, "\n\nstate %d\n\n", state); + print_core(state); + print_actions(state); +} + + +void +print_core(int state) +{ + register int i; + register int k; + register int rule; + register core *statep; + register short *sp; + register short *sp1; + + statep = state_table[state]; + k = statep->nitems; + + if (k == 0) return; + + for (i = 0; i < k; i++) + { + sp1 = sp = ritem + statep->items[i]; + + while (*sp > 0) + sp++; + + rule = -(*sp); + fprintf(foutput, " %s -> ", tags[rlhs[rule]]); + + for (sp = ritem + rrhs[rule]; sp < sp1; sp++) + { + fprintf(foutput, "%s ", tags[*sp]); + } + + putc('.', foutput); + + while (*sp > 0) + { + fprintf(foutput, " %s", tags[*sp]); + sp++; + } + + fprintf (foutput, " (rule %d)", rule); + putc('\n', foutput); + } + + putc('\n', foutput); +} + + +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; + + shiftp = shift_table[state]; + redp = reduction_table[state]; + errp = err_table[state]; + + if (!shiftp && !redp) + { + if (final_state == state) + fprintf(foutput, " $default\taccept\n"); + else + fprintf(foutput, " NO ACTIONS\n"); + return; + } + + if (shiftp) + { + k = shiftp->nshifts; + + for (i = 0; i < k; i++) + { + if (! shiftp->internalShifts[i]) continue; + state1 = shiftp->internalShifts[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 (i > 0) + putc('\n', foutput); + } + else + { + i = 0; + k = 0; + } + + if (errp) + { + int j, nerrs; + + nerrs = errp->nerrs; + + for (j = 0; j < nerrs; j++) + { + if (! errp->internalErrs[j]) continue; + symbol = errp->internalErrs[j]; + fprintf(foutput, " %-4s\terror (nonassociative)\n", tags[symbol]); + } + + if (j > 0) + 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]); + } + else if (redp) + { + print_reductions(state); + } + + if (i < k) + { + for (; i < k; i++) + { + if (! shiftp->internalShifts[i]) continue; + state1 = shiftp->internalShifts[i]; + symbol = accessing_symbol[state1]; + fprintf(foutput, " %-4s\tgo to state %d\n", tags[symbol], state1); + } + + putc('\n', foutput); + } +} + +#define END_TEST(end) \ + if (column + strlen(buffer) > (end)) \ + { fprintf (foutput, "%s\n ", buffer); column = 3; buffer[0] = 0; } \ + else + +void +print_grammar() +{ + int i, j; + short* rule; + char buffer[90]; + int column = 0; + + /* rule # : LHS -> RHS */ + 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]]); + rule = &ritem[rrhs[i]]; + if (*rule > 0) + while (*rule > 0) + fprintf(foutput, " %s", tags[*rule++]); + else + fputs (" /* empty */", 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]); + if (translations) + { + for (i = 0; i <= max_user_token_number; i++) + if (token_translations[i] != 2) + { + buffer[0] = 0; + column = strlen (tags[token_translations[i]]); + fprintf(foutput, "%s", tags[token_translations[i]]); + END_TEST (50); + sprintf (buffer, " (%d)", i); + + for (j = 1; j <= nrules; j++) + { + for (rule = &ritem[rrhs[j]]; *rule > 0; rule++) + if (*rule == token_translations[i]) + { + END_TEST (65); + sprintf (buffer + strlen(buffer), " %d", j); + break; + } + } + fprintf (foutput, "%s\n", buffer); + } + } + else + for (i = 1; i < ntokens; i++) + { + buffer[0] = 0; + column = strlen (tags[i]); + fprintf(foutput, "%s", tags[i]); + END_TEST (50); + sprintf (buffer, " (%d)", i); + + 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); + break; + } + } + fprintf (foutput, "%s\n", buffer); + } + + fputs("\nNonterminals, with rules where they appear\n\n", foutput); + for (i = ntokens; i <= nsyms - 1; i++) + { + int left_count = 0, right_count = 0; + + for (j = 1; j <= nrules; j++) + { + if (rlhs[j] == i) + left_count++; + for (rule = &ritem[rrhs[j]]; *rule > 0; rule++) + if (*rule == i) + { + right_count++; + break; + } + } + + buffer[0] = 0; + fprintf(foutput, "%s", tags[i]); + column = strlen (tags[i]); + sprintf (buffer, " (%d)", i); + END_TEST (0); + + if (left_count > 0) + { + END_TEST (50); + 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); + } + } + + if (right_count > 0) + { + if (left_count > 0) + sprintf (buffer + strlen(buffer), ","); + END_TEST (50); + 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); + break; + } + } + } + fprintf (foutput, "%s\n", buffer); + } +} |