X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/4f940944da24080103bdbcf9a61fbb222066d8db..9801d40c506b718971aed52c44975c7951bcb3bc:/src/output.c diff --git a/src/output.c b/src/output.c index 28a7992e..350d7ed8 100644 --- a/src/output.c +++ b/src/output.c @@ -122,89 +122,101 @@ static short *state_count = NULL; static short *order = NULL; static short *base = NULL; static short *pos = NULL; + +/* TABLE_SIZE is the allocated size of both TABLE and CHECK. + We start with the original hard-coded value: SHRT_MAX + (yes, not USHRT_MAX). */ +static size_t table_size = SHRT_MAX; static short *table = NULL; static short *check = NULL; static int lowzero; static int high; -struct obstack muscle_obstack; static struct obstack format_obstack; int error_verbose = 0; /*----------------------------------------------------------------. -| Format the FIRST and then TABLE_DATA[BEGIN..END[ into OOUT, and | -| return the number of bits needed for its longuest value. | +| If TABLE (and CHECK) appear to be small to be addressed at | +| DESIRED, grow them. Note that TABLE[DESIRED] is to be used, so | +| the desired size is at least DESIRED + 1. | `----------------------------------------------------------------*/ -static inline long int -output_short_table (struct obstack *oout, - short *table_data, - short first, - int begin, - int end) +static void +table_grow (size_t desired) { - long int max = first; - int i; - int j = 1; + size_t old_size = table_size; + + while (table_size <= desired) + table_size *= 2; + + if (trace_flag) + fprintf (stderr, "growing table and check from: %d to %d\n", + old_size, table_size); - obstack_fgrow1 (oout, "%6d", first); - for (i = begin; i < end; ++i) + table = XREALLOC (table, short, table_size); + check = XREALLOC (check, short, table_size); + + for (/* Nothing. */; old_size < table_size; ++old_size) { - obstack_1grow (oout, ','); - if (j >= 10) - { - obstack_sgrow (oout, "\n "); - j = 1; - } - else - ++j; - obstack_fgrow1 (oout, "%6d", table_data[i]); - if (table_data[i] > max) - max = table_data[i]; + table[old_size] = 0; + check[old_size] = -1; } - obstack_1grow (oout, 0); - - return max; } -/*--------------------. -| Similar, for ints. | -`--------------------*/ +/*-------------------------------------------------------------------. +| Create a function NAME which associates to the muscle NAME the | +| result of formatting the FIRST and then TABLE_DATA[BEGIN..END[ (of | +| TYPE), and to the muscle NAME_max, the max value of the | +| TABLE_DATA. | +`-------------------------------------------------------------------*/ -static inline long int -output_int_table (struct obstack *oout, - int *table_data, - int first, - int begin, - int end) -{ - long int max = first; - int i; - int j = 1; - obstack_fgrow1 (oout, "%6d", first); - for (i = begin; i < end; ++i) - { - obstack_1grow (oout, ','); - if (j >= 10) - { - obstack_sgrow (oout, "\n "); - j = 1; - } - else - ++j; - obstack_fgrow1 (oout, "%6d", table_data[i]); - if (table_data[i] > max) - max = table_data[i]; - } - obstack_1grow (oout, 0); - - return max; +#define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \ + \ +static void \ +Name (const char *name, \ + Type *table_data, \ + Type first, \ + int begin, \ + int end) \ +{ \ + Type max = first; \ + int i; \ + int j = 1; \ + \ + obstack_fgrow1 (&format_obstack, "%6d", first); \ + for (i = begin; i < end; ++i) \ + { \ + obstack_1grow (&format_obstack, ','); \ + if (j >= 10) \ + { \ + obstack_sgrow (&format_obstack, "\n "); \ + j = 1; \ + } \ + else \ + ++j; \ + obstack_fgrow1 (&format_obstack, "%6d", table_data[i]); \ + if (table_data[i] > max) \ + max = table_data[i]; \ + } \ + obstack_1grow (&format_obstack, 0); \ + muscle_insert (name, obstack_finish (&format_obstack)); \ + \ + /* Build `NAME_max' in the obstack. */ \ + obstack_fgrow1 (&format_obstack, "%s_max", name); \ + obstack_1grow (&format_obstack, 0); \ + MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), \ + (long int) max); \ } +GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table, unsigned int) +GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_short_table, short) +GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table, symbol_number_t) +GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_item_number_table, item_number_t) + /*-----------------------------------------------------------------. | Prepare the muscles related to the tokens: translate, tname, and | @@ -214,22 +226,20 @@ output_int_table (struct obstack *oout, static void prepare_tokens (void) { - long int max = output_short_table (&format_obstack, token_translations, + muscle_insert_symbol_number_table ("translate", + token_translations, 0, 1, max_user_token_number + 1); - muscle_insert ("translate", obstack_finish (&format_obstack)); - MUSCLE_INSERT_LONG_INT ("token_number_max", max); - XFREE (token_translations); { int i; int j = 0; for (i = 0; i < nsyms; i++) { - /* Be sure not to use twice the same quotearg slot. */ + /* Be sure not to use twice the same QUOTEARG slot: + SYMBOL_TAG_GET uses slot 0. */ const char *cp = quotearg_n_style (1, c_quoting_style, - quotearg_style (escape_quoting_style, - symbols[i]->tag)); + symbol_tag_get (symbols[i])); /* Width of the next token, including the two quotes, the coma and the space. */ int strsize = strlen (cp) + 2; @@ -259,9 +269,8 @@ prepare_tokens (void) short *values = XCALLOC (short, ntokens + 1); for (i = 0; i < ntokens + 1; ++i) values[i] = symbols[i]->user_token_number; - output_short_table (&format_obstack, values, - 0, 1, ntokens + 1); - muscle_insert ("toknum", obstack_finish (&format_obstack)); + muscle_insert_short_table ("toknum", values, + 0, 1, ntokens + 1); free (values); } } @@ -275,18 +284,17 @@ prepare_tokens (void) static void prepare_rules (void) { - long int max; - item_number_t *rhsp; int r; - int i = 0; + unsigned int i = 0; item_number_t *rhs = XMALLOC (item_number_t, nritems); - short *prhs = XMALLOC (short, nrules + 1); - short *r1 = XMALLOC (short, nrules + 1); - short *r2 = XMALLOC (short, nrules + 1); - short *rline = XMALLOC (short, nrules + 1); + unsigned int *prhs = XMALLOC (unsigned int, nrules + 1); + unsigned int *rline = XMALLOC (unsigned int, nrules + 1); + symbol_number_t *r1 = XMALLOC (symbol_number_t, nrules + 1); + unsigned int *r2 = XMALLOC (unsigned int, nrules + 1); for (r = 1; r < nrules + 1; ++r) { + item_number_t *rhsp; /* Index of rule R in RHS. */ prhs[r] = i; /* RHS of the rule R. */ @@ -299,28 +307,20 @@ prepare_rules (void) /* Separator in RHS. */ rhs[i++] = -1; /* Line where rule was defined. */ - rline[r] = rules[r].line; + rline[r] = rules[r].location.first_line; } assert (i == nritems); - max = output_int_table (&format_obstack, rhs, ritem[0], 1, nritems); - muscle_insert ("rhs", obstack_finish (&format_obstack)); - MUSCLE_INSERT_LONG_INT ("rhs_number_max", max); - - output_short_table (&format_obstack, prhs, 0, 1, nrules + 1); - muscle_insert ("prhs", obstack_finish (&format_obstack)); - - output_short_table (&format_obstack, rline, 0, 1, nrules + 1); - muscle_insert ("rline", obstack_finish (&format_obstack)); - - output_short_table (&format_obstack, r1, 0, 1, nrules + 1); - muscle_insert ("r1", obstack_finish (&format_obstack)); - - output_short_table (&format_obstack, r2, 0, 1, nrules + 1); - muscle_insert ("r2", obstack_finish (&format_obstack)); + muscle_insert_item_number_table ("rhs", rhs, ritem[0], 1, nritems); + muscle_insert_unsigned_int_table ("prhs", prhs, 0, 1, nrules + 1); + muscle_insert_unsigned_int_table ("rline", rline, 0, 1, nrules + 1); + muscle_insert_symbol_number_table ("r1", r1, 0, 1, nrules + 1); + muscle_insert_unsigned_int_table ("r2", r2, 0, 1, nrules + 1); free (rhs); free (prhs); + free (rline); + free (r1); free (r2); } @@ -332,12 +332,12 @@ static void prepare_states (void) { size_t i; - short *values = (short *) alloca (sizeof (short) * nstates); + symbol_number_t *values = + (symbol_number_t *) alloca (sizeof (symbol_number_t) * nstates); for (i = 0; i < nstates; ++i) values[i] = states[i]->accessing_symbol; - output_short_table (&format_obstack, values, - 0, 1, nstates); - muscle_insert ("stos", obstack_finish (&format_obstack)); + muscle_insert_symbol_number_table ("stos", values, + 0, 1, nstates); } @@ -380,8 +380,8 @@ action_row (state_t *state) for (j = 0; j < ntokens; j++) /* and record this rule as the rule to use if that token follows. */ - if (bitset_test (LA[state->lookaheadsp + i], j)) - actrow[j] = -LArule[state->lookaheadsp + i]->number; + if (bitset_test (state->lookaheads[i], j)) + actrow[j] = -state->lookaheads_rule[i]->number; } /* Now see which tokens are allowed for shifts in this state. For @@ -389,7 +389,7 @@ action_row (state_t *state) to reduce. */ for (i = 0; i < shiftp->nshifts; i++) { - int symbol; + symbol_number_t symbol; int shift_state = shiftp->shifts[i]; if (!shift_state) continue; @@ -428,7 +428,7 @@ action_row (state_t *state) for (i = 0; i < state->nlookaheads; i++) { int count = 0; - int rule = -LArule[state->lookaheadsp + i]->number; + int rule = -state->lookaheads_rule[i]->number; int j; for (j = 0; j < ntokens; j++) @@ -522,10 +522,8 @@ token_actions (void) save_row (i); } - output_short_table (&format_obstack, yydefact, - yydefact[0], 1, nstates); - muscle_insert ("defact", obstack_finish (&format_obstack)); - + muscle_insert_short_table ("defact", yydefact, + yydefact[0], 1, nstates); XFREE (actrow); XFREE (yydefact); } @@ -546,39 +544,11 @@ actions_output (FILE *out) if (!no_lines_flag) fprintf (out, muscle_find ("linef"), - rules[rule].action_line, + rules[rule].action_location.first_line, quotearg_style (c_quoting_style, muscle_find ("filename"))); - /* As a Bison extension, add the ending semicolon. Since some - Yacc don't do that, help people using bison as a Yacc - finding their missing semicolons. */ - fprintf (out, "{ %s%s }\n break;\n\n", - rules[rule].action, - yacc_flag ? ";" : ""); - } -} - - -/*----------------------------. -| Output the guards to OOUT. | -`----------------------------*/ - -void -guards_output (FILE *out) -{ - int rule; - for (rule = 1; rule < nrules + 1; ++rule) - if (rules[rule].guard) - { - fprintf (out, " case %d:\n", rule); - - if (!no_lines_flag) - fprintf (out, muscle_find ("linef"), - rules[rule].guard_line, - quotearg_style (c_quoting_style, - muscle_find ("filename"))); - fprintf (out, "{ %s; }\n break;\n\n", - rules[rule].guard); + fprintf (out, " %s\n break;\n\n", + rules[rule].action); } } @@ -597,33 +567,34 @@ token_definitions_output (FILE *out) symbol_t *symbol = symbols[i]; int number = symbol->user_token_number; - if (number == SALIAS) - continue; + /* At this stage, if there are literal aliases, they are part of + SYMBOLS, so we should not find symbols which are the aliases + here. */ + assert (number != USER_NUMBER_ALIAS); + /* Skip error token. */ if (symbol == errtoken) continue; - if (symbol->tag[0] == '\'') - continue; /* skip literal character */ - if (symbol->tag[0] == '\"') - { - /* use literal string only if given a symbol with an alias */ - if (symbol->alias) - symbol = symbol->alias; - else - continue; - } + + /* If this string has an alias, then it is necessarily the alias + which is to be output. */ + if (symbol->alias) + symbol = symbol->alias; + + /* Don't output literal chars or strings (when defined only as a + string). Note that must be done after the alias resolution: + think about `%token 'f' "f"'. */ + if (symbol->tag[0] == '\'' || symbol->tag[0] == '\"') + continue; /* Don't #define nonliteral tokens whose names contain periods or '$' (as does the default value of the EOF token). */ if (strchr (symbol->tag, '.') || strchr (symbol->tag, '$')) continue; - fprintf (out, "%s [[[%s]], [%d]]", + fprintf (out, "%s[[[%s]], [%d]]", first ? "" : ",\n", symbol->tag, number); - if (semantic_parser) - /* FIXME: This is probably wrong, and should be just as - above. --akim. */ - fprintf (out, "# define T%s\t%d\n", symbol->tag, symbol->number); + first = 0; } } @@ -716,10 +687,8 @@ goto_actions (void) yydefgoto[i - ntokens] = default_state; } - output_short_table (&format_obstack, yydefgoto, - yydefgoto[0], 1, nsyms - ntokens); - muscle_insert ("defgoto", obstack_finish (&format_obstack)); - + muscle_insert_short_table ("defgoto", yydefgoto, + yydefgoto[0], 1, nsyms - ntokens); XFREE (state_count); XFREE (yydefgoto); } @@ -793,8 +762,6 @@ matching_state (int vector) return -1; } -/* FIXME: For the time being, best approximation... */ -#define MAXTABLE SHRT_MAX static int pack_vector (int vector) @@ -808,7 +775,7 @@ pack_vector (int vector) assert (t); - for (j = lowzero - from[0]; j < MAXTABLE; j++) + for (j = lowzero - from[0]; j < (int) table_size; j++) { int k; int ok = 1; @@ -816,8 +783,8 @@ pack_vector (int vector) for (k = 0; ok && k < t; k++) { loc = j + from[k]; - if (loc > MAXTABLE) - fatal (_("maximum table size (%d) exceeded"), MAXTABLE); + if (loc > (int) table_size) + table_grow (loc); if (table[loc] != 0) ok = 0; @@ -860,8 +827,8 @@ pack_table (void) base = XCALLOC (short, nvectors); pos = XCALLOC (short, nentries); - table = XCALLOC (short, MAXTABLE); - check = XCALLOC (short, MAXTABLE); + table = XCALLOC (short, table_size); + check = XCALLOC (short, table_size); lowzero = 0; high = 0; @@ -869,7 +836,7 @@ pack_table (void) for (i = 0; i < nvectors; i++) base[i] = SHRT_MIN; - for (i = 0; i < MAXTABLE; i++) + for (i = 0; i < (int) table_size; i++) check[i] = -1; for (i = 0; i < nentries; i++) @@ -903,15 +870,12 @@ static void output_base (void) { /* Output pact. */ - output_short_table (&format_obstack, base, - base[0], 1, nstates); - muscle_insert ("pact", obstack_finish (&format_obstack)); + muscle_insert_short_table ("pact", base, + base[0], 1, nstates); /* Output pgoto. */ - output_short_table (&format_obstack, base, - base[nstates], nstates + 1, nvectors); - muscle_insert ("pgoto", obstack_finish (&format_obstack)); - + muscle_insert_short_table ("pgoto", base, + base[nstates], nstates + 1, nvectors); XFREE (base); } @@ -919,9 +883,8 @@ output_base (void) static void output_table (void) { - output_short_table (&format_obstack, table, - table[0], 1, high + 1); - muscle_insert ("table", obstack_finish (&format_obstack)); + muscle_insert_short_table ("table", table, + table[0], 1, high + 1); XFREE (table); } @@ -929,9 +892,8 @@ output_table (void) static void output_check (void) { - output_short_table (&format_obstack, check, - check[0], 1, high + 1); - muscle_insert ("check", obstack_finish (&format_obstack)); + muscle_insert_short_table ("check", check, + check[0], 1, high + 1); XFREE (check); } @@ -979,6 +941,46 @@ output_actions (void) } +/*----------------------. +| Run our backend, M4. | +`----------------------*/ + +static void +m4_invoke (const char *definitions) +{ + /* Invoke m4 on the definition of the muscles, and the skeleton. */ + const char *bison_pkgdatadir = getenv ("BISON_PKGDATADIR"); + const char *m4 = getenv ("M4"); + int pkg_data_len; + char *full_skeleton; + + if (!m4) + m4 = M4; + if (!bison_pkgdatadir) + bison_pkgdatadir = PKGDATADIR; + pkg_data_len = strlen (bison_pkgdatadir); + full_skeleton = XMALLOC (char, pkg_data_len + strlen (skeleton) + 2); + if (bison_pkgdatadir[pkg_data_len-1] == '/') + sprintf (full_skeleton, "%s%s", bison_pkgdatadir, skeleton); + else + sprintf (full_skeleton, "%s/%s", bison_pkgdatadir, skeleton); + if (trace_flag) + fprintf (stderr, + "running: %s -I %s m4sugar/m4sugar.m4 %s %s\n", + m4, bison_pkgdatadir, definitions, full_skeleton); + skel_in = readpipe (m4, + "-I", bison_pkgdatadir, + "m4sugar/m4sugar.m4", + definitions, + full_skeleton, + NULL); + XFREE (full_skeleton); + if (!skel_in) + error (EXIT_FAILURE, errno, "cannot run m4"); + skel_lex (); + +} + /*---------------------------. | Call the skeleton parser. | `---------------------------*/ @@ -1013,10 +1015,6 @@ output_skeleton (void) actions_output (out); fputs ("]])\n\n", out); - fputs ("m4_define([b4_guards], \n[[", out); - guards_output (out); - fputs ("]])\n\n", out); - fputs ("m4_define([b4_tokens], \n[", out); token_definitions_output (out); fputs ("])\n\n", out); @@ -1027,32 +1025,13 @@ output_skeleton (void) fputs ("m4_divert_push(0)dnl\n", out); xfclose (out); - /* Invoke m4 on the definition of the muscles, and the skeleton. */ - { - const char *bison_pkgdatadir = getenv ("BISON_PKGDATADIR"); - const char *m4 = getenv ("M4"); - if (!m4) - m4 = M4; - if (!bison_pkgdatadir) - bison_pkgdatadir = PKGDATADIR; - if (trace_flag) - fprintf (stderr, - "running: %s -I %s m4sugar/m4sugar.m4 %s %s\n", - m4, bison_pkgdatadir, tempfile, skeleton); - skel_in = readpipe (m4, - "-I", bison_pkgdatadir, - "m4sugar/m4sugar.m4", - tempfile, - skeleton, - NULL); - if (!skel_in) - error (EXIT_FAILURE, errno, "cannot run m4"); - skel_lex (); - - /* If `debugging', keep this file alive. */ - if (!trace_flag) - unlink (tempfile); - } + m4_invoke (tempfile); + + /* If `debugging', keep this file alive. */ + if (!trace_flag) + unlink (tempfile); + + free (tempfile); } static void @@ -1085,17 +1064,14 @@ prepare (void) MUSCLE_INSERT_INT ("defines_flag", defines_flag); /* Copy definitions in directive. */ - obstack_1grow (&attrs_obstack, 0); - muscle_insert ("prologue", obstack_finish (&attrs_obstack)); + obstack_1grow (&pre_prologue_obstack, 0); + obstack_1grow (&post_prologue_obstack, 0); + muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack)); + muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack)); /* Find the right skeleton file. */ if (!skeleton) - { - if (semantic_parser) - skeleton = "bison.hairy"; - else - skeleton = "bison.simple"; - } + skeleton = "bison.simple"; /* Parse the skeleton file and output the needed parsers. */ muscle_insert ("skeleton", skeleton); @@ -1121,8 +1097,7 @@ output (void) /* Process the selected skeleton file. */ output_skeleton (); - obstack_free (&muscle_obstack, NULL); obstack_free (&format_obstack, NULL); - obstack_free (&action_obstack, NULL); - obstack_free (&attrs_obstack, NULL); + obstack_free (&pre_prologue_obstack, NULL); + obstack_free (&post_prologue_obstack, NULL); }