X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/92b16366ddbf8aca3974852048f97e8045e77e1d..8adfa272f72683102c45cc6eaba00aaa5db2497a:/src/output.c diff --git a/src/output.c b/src/output.c index 693a45b1..34ff7d36 100644 --- a/src/output.c +++ b/src/output.c @@ -91,7 +91,6 @@ */ #include "system.h" -#include "obstack.h" #include "quotearg.h" #include "getargs.h" #include "files.h" @@ -122,18 +121,33 @@ static int lowzero; static int high; struct obstack muscle_obstack; -struct obstack output_obstack; +static struct obstack format_obstack; int error_verbose = 0; +/* Returns the number of lines of S. */ +static size_t +get_lines_number (const char *s) +{ + size_t lines = 0; + + size_t i; + for (i = 0; s[i]; ++i) + if (s[i] == '\n') + ++lines; + + return lines; +} + + /* FIXME. */ static inline void output_table_data (struct obstack *oout, short *table_data, short first, - short begin, - short end) + int begin, + int end) { int i; int j = 1; @@ -158,9 +172,9 @@ output_table_data (struct obstack *oout, static void output_token_translations (void) { - output_table_data (&output_obstack, token_translations, + output_table_data (&format_obstack, token_translations, 0, 1, max_user_token_number + 1); - muscle_insert ("translate", obstack_finish (&output_obstack)); + muscle_insert ("translate", obstack_finish (&format_obstack)); XFREE (token_translations); } @@ -173,12 +187,12 @@ output_gram (void) short *values = XCALLOC (short, nrules + 1); for (i = 0; i < nrules + 1; ++i) values[i] = rule_table[i].rhs; - output_table_data (&output_obstack, values, + output_table_data (&format_obstack, values, 0, 1, nrules + 1); XFREE (values); } - muscle_insert ("prhs", obstack_finish (&output_obstack)); + muscle_insert ("prhs", obstack_finish (&format_obstack)); { size_t yyrhs_size = 1; @@ -192,15 +206,15 @@ output_gram (void) for (sp = ritem + 1, i = 1; *sp; ++sp, ++i) yyrhs[i] = *sp > 0 ? *sp : 0; - output_table_data (&output_obstack, yyrhs, + output_table_data (&format_obstack, yyrhs, ritem[0], 1, yyrhs_size); - muscle_insert ("rhs", obstack_finish (&output_obstack)); + muscle_insert ("rhs", obstack_finish (&format_obstack)); XFREE (yyrhs); } #if 0 - if (!semantic_parser && !no_parser_flag) + if (!semantic_parser) obstack_sgrow (&table_obstack, "\n#endif\n"); #endif } @@ -212,10 +226,10 @@ output_stos (void) int i; short *values = (short *) alloca (sizeof (short) * nstates); for (i = 0; i < nstates; ++i) - values[i] = state_table[i].accessing_symbol; - output_table_data (&output_obstack, values, + values[i] = state_table[i]->accessing_symbol; + output_table_data (&format_obstack, values, 0, 1, nstates); - muscle_insert ("stos", obstack_finish (&output_obstack)); + muscle_insert ("stos", obstack_finish (&format_obstack)); } @@ -230,78 +244,54 @@ output_rule_data (void) short *values = XCALLOC (short, nrules + 1); for (i = 0; i < nrules + 1; ++i) values[i] = rule_table[i].line; - output_table_data (&output_obstack, values, + output_table_data (&format_obstack, values, 0, 1, nrules + 1); - muscle_insert ("rline", obstack_finish (&output_obstack)); + muscle_insert ("rline", obstack_finish (&format_obstack)); XFREE (values); } j = 0; for (i = 0; i < nsyms; i++) - /* this used to be i<=nsyms, but that output a final "" symbol - almost by accident */ { + /* Be sure not to use twice the same quotearg slot. */ + const char *cp = + quotearg_n_style (1, c_quoting_style, + quotearg_style (escape_quoting_style, tags[i])); /* Width of the next token, including the two quotes, the coma and the space. */ - int strsize = 4; - char *p; - - for (p = tags[i]; p && *p; p++) - if (*p == '"' || *p == '\\' || *p == '\n' || *p == '\t' - || *p == '\b') - strsize += 2; - else if (*p < 040 || *p >= 0177) - strsize += 4; - else - strsize++; + int strsize = strlen (cp) + 2; if (j + strsize > 75) { - obstack_sgrow (&output_obstack, "\n "); + obstack_sgrow (&format_obstack, "\n "); j = 2; } - obstack_1grow (&output_obstack, '\"'); - for (p = tags[i]; p && *p; p++) - { - if (*p == '"' || *p == '\\') - obstack_fgrow1 (&output_obstack, "\\%c", *p); - else if (*p == '\n') - obstack_sgrow (&output_obstack, "\\n"); - else if (*p == '\t') - obstack_sgrow (&output_obstack, "\\t"); - else if (*p == '\b') - obstack_sgrow (&output_obstack, "\\b"); - else if (*p < 040 || *p >= 0177) - obstack_fgrow1 (&output_obstack, "\\%03o", *p); - else - obstack_1grow (&output_obstack, *p); - } - - obstack_sgrow (&output_obstack, "\", "); + obstack_sgrow (&format_obstack, cp); + obstack_sgrow (&format_obstack, ", "); j += strsize; } /* add a NULL entry to list of tokens */ - obstack_sgrow (&output_obstack, "NULL"); + obstack_sgrow (&format_obstack, "NULL"); /* Finish table and store. */ - obstack_1grow (&output_obstack, 0); - muscle_insert ("tname", obstack_finish (&output_obstack)); + obstack_1grow (&format_obstack, 0); + muscle_insert ("tname", obstack_finish (&format_obstack)); /* Output YYTOKNUM. */ - output_table_data (&output_obstack, user_toknums, + output_table_data (&format_obstack, user_toknums, 0, 1, ntokens + 1); - muscle_insert ("toknum", obstack_finish (&output_obstack)); + muscle_insert ("toknum", obstack_finish (&format_obstack)); /* Output YYR1. */ { short *values = XCALLOC (short, nrules + 1); for (i = 0; i < nrules + 1; ++i) values[i] = rule_table[i].lhs; - output_table_data (&output_obstack, values, + output_table_data (&format_obstack, values, 0, 1, nrules + 1); - muscle_insert ("r1", obstack_finish (&output_obstack)); + muscle_insert ("r1", obstack_finish (&format_obstack)); XFREE (values); } @@ -310,12 +300,10 @@ output_rule_data (void) for (i = 1; i < nrules; i++) short_tab[i] = rule_table[i + 1].rhs - rule_table[i].rhs - 1; short_tab[nrules] = nitems - rule_table[nrules].rhs - 1; - output_table_data (&output_obstack, short_tab, + output_table_data (&format_obstack, short_tab, 0, 1, nrules + 1); - muscle_insert ("r2", obstack_finish (&output_obstack)); + muscle_insert ("r2", obstack_finish (&format_obstack)); XFREE (short_tab); - - XFREE (rule_table + 1); } /*------------------------------------------------------------------. @@ -333,63 +321,45 @@ output_rule_data (void) `------------------------------------------------------------------*/ static int -action_row (int state) +action_row (state_t *state) { int i; - int j; - int k; - int m = 0; - int n = 0; - int default_rule; - int nreds; - int rule; - int shift_state; - int symbol; - reductions *redp; - shifts *shiftp; - errs *errp; - int nodefault = 0; /* set nonzero to inhibit having any default reduction */ + int default_rule = 0; + reductions *redp = state->reductions; + shifts *shiftp = state->shifts; + errs *errp = state->errs; + /* set nonzero to inhibit having any default reduction */ + int nodefault = 0; for (i = 0; i < ntokens; i++) actrow[i] = 0; - default_rule = 0; - nreds = 0; - redp = state_table[state].reductions; - - if (redp) + if (redp->nreds >= 1) { - nreds = redp->nreds; - - if (nreds >= 1) - { - /* loop over all the rules available here which require - lookahead */ - m = state_table[state].lookaheads; - n = state_table[state + 1].lookaheads; - - for (i = n - 1; i >= m; i--) - /* and find each token which the rule finds acceptable - to come next */ - for (j = 0; j < ntokens; j++) - /* and record this rule as the rule to use if that - token follows. */ - if (BITISSET (LA (i), j)) - actrow[j] = -LAruleno[i]; - } + int j; + /* loop over all the rules available here which require + lookahead */ + for (i = state->nlookaheads - 1; i >= 0; --i) + /* and find each token which the rule finds acceptable + to come next */ + for (j = 0; j < ntokens; j++) + /* and record this rule as the rule to use if that + token follows. */ + if (BITISSET (LA (state->lookaheadsp + i), j)) + actrow[j] = -LAruleno[state->lookaheadsp + i]; } /* Now see which tokens are allowed for shifts in this state. For them, record the shift as the thing to do. So shift is preferred to reduce. */ - shiftp = state_table[state].shifts; for (i = 0; i < shiftp->nshifts; i++) { - shift_state = shiftp->shifts[i]; + int symbol; + int shift_state = shiftp->shifts[i]; if (!shift_state) continue; - symbol = state_table[shift_state].accessing_symbol; + symbol = state_table[shift_state]->accessing_symbol; if (ISVAR (symbol)) break; @@ -404,39 +374,31 @@ action_row (int state) /* See which tokens are an explicit error in this state (due to %nonassoc). For them, record MINSHORT as the action. */ - errp = state_table[state].errs; - - if (errp) + for (i = 0; i < errp->nerrs; i++) { - k = errp->nerrs; - - for (i = 0; i < k; i++) - { - symbol = errp->errs[i]; - actrow[symbol] = MINSHORT; - } + int symbol = errp->errs[i]; + actrow[symbol] = MINSHORT; } /* Now find the most common reduction and make it the default action for this state. */ - if (nreds >= 1 && !nodefault) + if (redp->nreds >= 1 && !nodefault) { - if (state_table[state].consistent) + if (state->consistent) default_rule = redp->rules[0]; else { int max = 0; - for (i = m; i < n; i++) + for (i = 0; i < state->nlookaheads; i++) { int count = 0; - rule = -LAruleno[i]; + int rule = -LAruleno[state->lookaheadsp + i]; + int j; for (j = 0; j < ntokens; j++) - { - if (actrow[j] == rule) - count++; - } + if (actrow[j] == rule) + count++; if (count > max) { @@ -450,11 +412,10 @@ action_row (int state) if (max > 0) { + int j; for (j = 0; j < ntokens; j++) - { - if (actrow[j] == default_rule) - actrow[j] = 0; - } + if (actrow[j] == default_rule) + actrow[j] = 0; default_rule = -default_rule; } @@ -465,11 +426,9 @@ action_row (int state) So replace any action which says "error" with "use default". */ if (default_rule == 0) - for (j = 0; j < ntokens; j++) - { - if (actrow[j] == MINSHORT) - actrow[j] = 0; - } + for (i = 0; i < ntokens; i++) + if (actrow[i] == MINSHORT) + actrow[i] = 0; return default_rule; } @@ -486,10 +445,8 @@ save_row (int state) count = 0; for (i = 0; i < ntokens; i++) - { - if (actrow[i] != 0) - count++; - } + if (actrow[i] != 0) + count++; if (count == 0) return; @@ -498,13 +455,11 @@ save_row (int state) tos[state] = sp2 = XCALLOC (short, count); for (i = 0; i < ntokens; i++) - { - if (actrow[i] != 0) - { - *sp1++ = i; - *sp2++ = actrow[i]; - } - } + if (actrow[i] != 0) + { + *sp1++ = i; + *sp2++ = actrow[i]; + } tally[state] = count; width[state] = sp1[-1] - sp[0] + 1; @@ -528,19 +483,87 @@ token_actions (void) actrow = XCALLOC (short, ntokens); for (i = 0; i < nstates; ++i) { - yydefact[i] = action_row (i); + yydefact[i] = action_row (state_table[i]); save_row (i); } - output_table_data (&output_obstack, yydefact, + output_table_data (&format_obstack, yydefact, yydefact[0], 1, nstates); - muscle_insert ("defact", obstack_finish (&output_obstack)); + muscle_insert ("defact", obstack_finish (&format_obstack)); XFREE (actrow); XFREE (yydefact); } +/*-----------------------------. +| Output the actions to OOUT. | +`-----------------------------*/ + +static void +actions_output (FILE *out, size_t *line) +{ + int rule; + for (rule = 1; rule < nrules + 1; ++rule) + if (rule_table[rule].action) + { + fprintf (out, " case %d:\n", rule); + + if (!no_lines_flag) + fprintf (out, muscle_find ("linef"), + rule_table[rule].action_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", + rule_table[rule].action, + yacc_flag ? ";" : ""); + + /* We always output 4 '\n' per action. */ + *line += 4; + /* Plus one if !no_lines_flag. */ + if (!no_lines_flag) + ++*line; + /* Get the number of lines written by the user. */ + *line += get_lines_number (rule_table[rule].action); + } +} + + +/*----------------------------. +| Output the guards to OOUT. | +`----------------------------*/ + +static void +guards_output (FILE *out, size_t *line) +{ + int rule; + for (rule = 1; rule < nrules + 1; ++rule) + if (rule_table[rule].action) + { + fprintf (out, " case %d:\n", rule); + + if (!no_lines_flag) + fprintf (out, muscle_find ("linef"), + rule_table[rule].guard_line, + quotearg_style (c_quoting_style, + muscle_find ("filename"))); + fprintf (out, "{ %s; }\n break;\n\n", + rule_table[rule].guard); + + /* We always output 4 '\n' per action. */ + *line += 4; + /* Plus one if !no_lines_flag. */ + if (!no_lines_flag) + ++*line; + /* Get the number of lines written by the user. */ + *line += get_lines_number (rule_table[rule].guard); + } +} + + static void save_column (int symbol, int default_state) { @@ -549,34 +572,28 @@ save_column (int symbol, int default_state) short *sp1; short *sp2; int count; - int symno; + int symno = symbol - ntokens + nstates; short begin = goto_map[symbol]; short end = goto_map[symbol + 1]; count = 0; for (i = begin; i < end; i++) - { - if (to_state[i] != default_state) - count++; - } + if (to_state[i] != default_state) + count++; if (count == 0) return; - symno = symbol - ntokens + nstates; - froms[symno] = sp1 = sp = XCALLOC (short, count); tos[symno] = sp2 = XCALLOC (short, count); for (i = begin; i < end; i++) - { - if (to_state[i] != default_state) - { - *sp1++ = from_state[i]; - *sp2++ = to_state[i]; - } - } + if (to_state[i] != default_state) + { + *sp1++ = from_state[i]; + *sp2++ = to_state[i]; + } tally[symno] = count; width[symno] = sp1[-1] - sp[0] + 1; @@ -586,13 +603,10 @@ static int default_goto (int symbol) { int i; - int m; - int n; - int default_state; - int max; - - m = goto_map[symbol]; - n = goto_map[symbol + 1]; + int m = goto_map[symbol]; + int n = goto_map[symbol + 1]; + int default_state = -1; + int max = 0; if (m == n) return -1; @@ -603,17 +617,12 @@ default_goto (int symbol) for (i = m; i < n; i++) state_count[to_state[i]]++; - max = 0; - default_state = -1; - for (i = 0; i < nstates; i++) - { - if (state_count[i] > max) - { - max = state_count[i]; - default_state = i; - } - } + if (state_count[i] > max) + { + max = state_count[i]; + default_state = i; + } return default_state; } @@ -642,9 +651,9 @@ goto_actions (void) yydefgoto[i - ntokens] = default_state; } - output_table_data (&output_obstack, yydefgoto, + output_table_data (&format_obstack, yydefgoto, yydefgoto[0], 1, nsyms - ntokens); - muscle_insert ("defgoto", obstack_finish (&output_obstack)); + muscle_insert ("defgoto", obstack_finish (&format_obstack)); XFREE (state_count); XFREE (yydefgoto); @@ -658,50 +667,41 @@ static void sort_actions (void) { int i; - int j; - int k; - int t; - int w; order = XCALLOC (short, nvectors); nentries = 0; for (i = 0; i < nvectors; i++) - { - if (tally[i] > 0) - { - t = tally[i]; - w = width[i]; - j = nentries - 1; + if (tally[i] > 0) + { + int k; + int t = tally[i]; + int w = width[i]; + int j = nentries - 1; - while (j >= 0 && (width[order[j]] < w)) - j--; + while (j >= 0 && (width[order[j]] < w)) + j--; - while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t)) - j--; + while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t)) + j--; - for (k = nentries - 1; k > j; k--) - order[k + 1] = order[k]; + for (k = nentries - 1; k > j; k--) + order[k + 1] = order[k]; - order[j + 1] = i; - nentries++; - } - } + order[j + 1] = i; + nentries++; + } } static int matching_state (int vector) { - int i; - int j; - int k; + int i = order[vector]; int t; int w; - int match; int prev; - i = order[vector]; if (i >= nstates) return -1; @@ -710,16 +710,16 @@ matching_state (int vector) for (prev = vector - 1; prev >= 0; prev--) { - j = order[prev]; + int j = order[prev]; + int k; + int match = 1; + if (width[j] != w || tally[j] != t) return -1; - match = 1; for (k = 0; match && k < t; k++) - { - if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k]) - match = 0; - } + if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k]) + match = 0; if (match) return j; @@ -732,26 +732,19 @@ matching_state (int vector) static int pack_vector (int vector) { - int i; + int i = order[vector]; int j; - int k; - int t; + int t = tally[i]; int loc = 0; - int ok; - short *from; - short *to; - - i = order[vector]; - t = tally[i]; + short *from = froms[i]; + short *to = tos[i]; assert (t); - from = froms[i]; - to = tos[i]; - for (j = lowzero - from[0]; j < MAXTABLE; j++) { - ok = 1; + int k; + int ok = 1; for (k = 0; ok && k < t; k++) { @@ -764,10 +757,8 @@ pack_vector (int vector) } for (k = 0; ok && k < vector; k++) - { - if (pos[k] == j) - ok = 0; - } + if (pos[k] == j) + ok = 0; if (ok) { @@ -787,8 +778,8 @@ pack_vector (int vector) return j; } } - - assert (!"pack_vector"); +#define pack_vector_succeeded 0 + assert (pack_vector_succeeded); return 0; } @@ -829,10 +820,8 @@ pack_table (void) for (i = 0; i < nvectors; i++) { - if (froms[i]) - XFREE (froms[i]); - if (tos[i]) - XFREE (tos[i]); + XFREE (froms[i]); + XFREE (tos[i]); } XFREE (froms); @@ -847,14 +836,14 @@ static void output_base (void) { /* Output pact. */ - output_table_data (&output_obstack, base, + output_table_data (&format_obstack, base, base[0], 1, nstates); - muscle_insert ("pact", obstack_finish (&output_obstack)); + muscle_insert ("pact", obstack_finish (&format_obstack)); /* Output pgoto. */ - output_table_data (&output_obstack, base, + output_table_data (&format_obstack, base, base[nstates], nstates + 1, nvectors); - muscle_insert ("pgoto", obstack_finish (&output_obstack)); + muscle_insert ("pgoto", obstack_finish (&format_obstack)); XFREE (base); } @@ -863,9 +852,9 @@ output_base (void) static void output_table (void) { - output_table_data (&output_obstack, table, + output_table_data (&format_obstack, table, table[0], 1, high + 1); - muscle_insert ("table", obstack_finish (&output_obstack)); + muscle_insert ("table", obstack_finish (&format_obstack)); XFREE (table); } @@ -873,9 +862,9 @@ output_table (void) static void output_check (void) { - output_table_data (&output_obstack, check, + output_table_data (&format_obstack, check, check[0], 1, high + 1); - muscle_insert ("check", obstack_finish (&output_obstack)); + muscle_insert ("check", obstack_finish (&format_obstack)); XFREE (check); } @@ -885,6 +874,7 @@ output_check (void) static void output_actions (void) { + int i; nvectors = nstates + nvars; froms = XCALLOC (short *, nvectors); @@ -893,8 +883,6 @@ output_actions (void) width = XCALLOC (short, nvectors); token_actions (); - LIST_FREE (shifts, first_shift); - LIST_FREE (reductions, first_reduction); XFREE (LA); XFREE (LAruleno); @@ -910,6 +898,14 @@ output_actions (void) output_table (); output_check (); + + for (i = 0; i < nstates; ++i) + { + free (state_table[i]->shifts); + XFREE (state_table[i]->reductions); + free (state_table[i]->errs); + free (state_table[i]); + } XFREE (state_table); } @@ -920,24 +916,29 @@ output_actions (void) `------------------------------------------------------------*/ static void -output_parser (const char *skel_filename, struct obstack *oout) +output_parser (const char *skel_filename, FILE *out) { int c; FILE *fskel; - size_t line; + size_t output_line; + size_t skeleton_line; fskel = xfopen (skel_filename, "r"); /* New output code. */ - line = 1; + output_line = 1; + skeleton_line = 1; c = getc (fskel); while (c != EOF) { if (c != '%') { if (c == '\n') - ++line; - obstack_1grow (oout, c); + { + ++output_line; + ++skeleton_line; + } + putc (c, out); c = getc (fskel); } else if ((c = getc (fskel)) == '%') @@ -953,20 +954,27 @@ output_parser (const char *skel_filename, struct obstack *oout) /* Output the right value, or see if it's something special. */ muscle_key = obstack_finish (&muscle_obstack); muscle_value = muscle_find (muscle_key); - if (muscle_value) - obstack_sgrow (oout, muscle_value); + if (!strcmp (muscle_key, "actions")) + actions_output (out, &output_line); + else if (!strcmp (muscle_key, "guards")) + guards_output (out, &output_line); else if (!strcmp (muscle_key, "line")) - obstack_fgrow1 (oout, "%d", line + 1); - else if (!strcmp (muscle_key, "input-line")) - obstack_fgrow1 (oout, "%d", lineno); + fprintf (out, "%d", output_line); + else if (!strcmp (muscle_key, "skeleton-line")) + fprintf (out, "%d", skeleton_line); + else if (muscle_value) + { + fputs (muscle_value, out); + output_line += get_lines_number (muscle_value); + } else { - obstack_sgrow (oout, "%%"); - obstack_sgrow (oout, muscle_key); + fputs ("%%", out); + fputs (muscle_key, out); } } else - obstack_1grow (oout, '%'); + putc ('%', out); } /* End. */ @@ -980,6 +988,7 @@ output_parser (const char *skel_filename, struct obstack *oout) static void output_master_parser (void) { + FILE *parser = xfopen (parser_file_name, "w"); if (!skeleton) { if (semantic_parser) @@ -988,7 +997,10 @@ output_master_parser (void) skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE); } muscle_insert ("skeleton", skeleton); - output_parser (skeleton, &table_obstack); + muscle_insert ("parser-file-name", parser_file_name); + + output_parser (skeleton, parser); + xfclose (parser); } @@ -1025,8 +1037,8 @@ prepare (void) MUSCLE_INSERT_INT ("debug", debug_flag); MUSCLE_INSERT_INT ("final", final_state); MUSCLE_INSERT_INT ("maxtok", max_user_token_number); - MUSCLE_INSERT_INT ("ntbase", ntokens); MUSCLE_INSERT_INT ("error-verbose", error_verbose); + MUSCLE_INSERT_STRING ("prefix", spec_name_prefix); MUSCLE_INSERT_INT ("nnts", nvars); MUSCLE_INSERT_INT ("nrules", nrules); @@ -1034,14 +1046,50 @@ prepare (void) MUSCLE_INSERT_INT ("ntokens", ntokens); MUSCLE_INSERT_INT ("locations-flag", locations_flag); +} + + +/*-------------------------. +| Output the header file. | +`-------------------------*/ + +static void +header_output (void) +{ + FILE *out = xfopen (spec_defines_file, "w"); + char *macro_name = compute_header_macro (); + + fprintf (out, "#ifndef %s\n", macro_name); + fprintf (out, "# define %s\n\n", macro_name); + + fputs (muscle_find ("tokendef"), out); + fprintf (out, "\ +#ifndef YYSTYPE\n\ +typedef %s +yystype;\n\ +# define YYSTYPE yystype\n\ +#endif\n", + muscle_find ("stype")); + + if (!pure_parser) + fprintf (out, "\nextern YYSTYPE %slval;\n", + spec_name_prefix); + if (semantic_parser) + { + int i; - /* We need to save the actions in the muscle %%action. */ - muscle_insert ("action", obstack_finish (&action_obstack)); + for (i = ntokens; i < nsyms; i++) + /* don't make these for dummy nonterminals made by gensym. */ + if (*tags[i] != '@') + fprintf (out, "# define NT%s\t%d\n", tags[i], i); + } - if (spec_name_prefix) - MUSCLE_INSERT_STRING ("prefix", spec_name_prefix); + fprintf (out, "\n#endif /* not %s */\n", macro_name); + free (macro_name); + xfclose (out); } + /*----------------------------------------------------------. | Output the parsing tables and the parser code to ftable. | `----------------------------------------------------------*/ @@ -1049,9 +1097,7 @@ prepare (void) void output (void) { - obstack_init (&output_obstack); - - LIST_FREE (core, first_state); + obstack_init (&format_obstack); output_token_translations (); output_gram (); @@ -1063,16 +1109,20 @@ output (void) XFREE (user_toknums); output_actions (); -#if 0 - if (!no_parser_flag) */ -#endif prepare (); /* Copy definitions in directive. */ + obstack_1grow (&attrs_obstack, 0); muscle_insert ("prologue", obstack_finish (&attrs_obstack)); + /* Output the parser. */ output_master_parser (); - - obstack_free (&muscle_obstack, 0); - obstack_free (&output_obstack, 0); - obstack_free (&action_obstack, 0); + /* Output the header if needed. */ + if (defines_flag) + header_output (); + + free (rule_table + 1); + obstack_free (&muscle_obstack, NULL); + obstack_free (&format_obstack, NULL); + obstack_free (&action_obstack, NULL); + obstack_free (&attrs_obstack, NULL); }