diff options
author | Baptiste Daroussin <bapt@FreeBSD.org> | 2012-05-21 13:31:26 +0000 |
---|---|---|
committer | Baptiste Daroussin <bapt@FreeBSD.org> | 2012-05-21 13:31:26 +0000 |
commit | 98e903e7a0e26ebb7bec65bfe7f9a6b0d19dd966 (patch) | |
tree | c752c1d24d195a334247f36888203a7e2bce0837 /contrib/byacc/output.c | |
parent | c7e5232438a12e0798143b73dbae712a06ed0dee (diff) | |
parent | aec86590e4a004278acba93b5e6df2aee860b36d (diff) | |
download | src-98e903e7a0e26ebb7bec65bfe7f9a6b0d19dd966.tar.gz src-98e903e7a0e26ebb7bec65bfe7f9a6b0d19dd966.zip |
Notes
Diffstat (limited to 'contrib/byacc/output.c')
-rw-r--r-- | contrib/byacc/output.c | 1507 |
1 files changed, 1507 insertions, 0 deletions
diff --git a/contrib/byacc/output.c b/contrib/byacc/output.c new file mode 100644 index 000000000000..33b10c6c5df1 --- /dev/null +++ b/contrib/byacc/output.c @@ -0,0 +1,1507 @@ +/* $Id: output.c,v 1.43 2012/01/14 17:03:52 tom Exp $ */ + +#include "defs.h" + +#define StaticOrR (rflag ? "" : "static ") +#define CountLine(fp) (!rflag || ((fp) == code_file)) + +static int nvectors; +static int nentries; +static Value_t **froms; +static Value_t **tos; +static Value_t *tally; +static Value_t *width; +static Value_t *state_count; +static Value_t *order; +static Value_t *base; +static Value_t *pos; +static int maxtable; +static Value_t *table; +static Value_t *check; +static int lowzero; +static int high; + +static void +putc_code(FILE * fp, int c) +{ + if ((c == '\n') && (fp == code_file)) + ++outline; + putc(c, fp); +} + +static void +putl_code(FILE * fp, const char *s) +{ + if (fp == code_file) + ++outline; + fputs(s, fp); +} + +static void +puts_code(FILE * fp, const char *s) +{ + fputs(s, fp); +} + +static void +write_code_lineno(FILE * fp) +{ + if (!lflag && (fp == code_file)) + { + ++outline; + fprintf(fp, line_format, outline, code_file_name); + } +} + +static void +write_input_lineno(void) +{ + if (!lflag) + { + ++outline; + fprintf(code_file, line_format, lineno, input_file_name); + } +} + +static void +define_prefixed(FILE * fp, const char *name) +{ + int bump_line = CountLine(fp); + if (bump_line) + ++outline; + fprintf(fp, "\n"); + + if (bump_line) + ++outline; + fprintf(fp, "#ifndef %s\n", name); + + if (bump_line) + ++outline; + fprintf(fp, "#define %-10s %s%s\n", name, symbol_prefix, name + 2); + + if (bump_line) + ++outline; + fprintf(fp, "#endif /* %s */\n", name); +} + +static void +output_prefix(FILE * fp) +{ + if (symbol_prefix == NULL) + { + symbol_prefix = "yy"; + } + else + { + define_prefixed(fp, "yyparse"); + define_prefixed(fp, "yylex"); + define_prefixed(fp, "yyerror"); + define_prefixed(fp, "yychar"); + define_prefixed(fp, "yyval"); + define_prefixed(fp, "yylval"); + define_prefixed(fp, "yydebug"); + define_prefixed(fp, "yynerrs"); + define_prefixed(fp, "yyerrflag"); + define_prefixed(fp, "yylhs"); + define_prefixed(fp, "yylen"); + define_prefixed(fp, "yydefred"); + define_prefixed(fp, "yydgoto"); + define_prefixed(fp, "yysindex"); + define_prefixed(fp, "yyrindex"); + define_prefixed(fp, "yygindex"); + define_prefixed(fp, "yytable"); + define_prefixed(fp, "yycheck"); + define_prefixed(fp, "yyname"); + define_prefixed(fp, "yyrule"); + } + if (CountLine(fp)) + ++outline; + fprintf(fp, "#define YYPREFIX \"%s\"\n", symbol_prefix); +} + +static void +output_newline(void) +{ + if (!rflag) + ++outline; + putc('\n', output_file); +} + +static void +output_line(const char *value) +{ + fputs(value, output_file); + output_newline(); +} + +static void +output_int(int value) +{ + fprintf(output_file, "%5d,", value); +} + +static void +start_int_table(const char *name, int value) +{ + int need = 34 - (int)(strlen(symbol_prefix) + strlen(name)); + + if (need < 6) + need = 6; + fprintf(output_file, + "%sconst short %s%s[] = {%*d,", + StaticOrR, symbol_prefix, name, need, value); +} + +static void +start_str_table(const char *name) +{ + fprintf(output_file, + "%sconst char *%s%s[] = {", + StaticOrR, "yy", name); + output_newline(); +} + +static void +end_table(void) +{ + output_newline(); + output_line("};"); +} + +static void +output_rule_data(void) +{ + int i; + int j; + + start_int_table("lhs", symbol_value[start_symbol]); + + j = 10; + for (i = 3; i < nrules; i++) + { + if (j >= 10) + { + output_newline(); + j = 1; + } + else + ++j; + + output_int(symbol_value[rlhs[i]]); + } + end_table(); + + start_int_table("len", 2); + + j = 10; + for (i = 3; i < nrules; i++) + { + if (j >= 10) + { + output_newline(); + j = 1; + } + else + j++; + + output_int(rrhs[i + 1] - rrhs[i] - 1); + } + end_table(); +} + +static void +output_yydefred(void) +{ + int i, j; + + start_int_table("defred", (defred[0] ? defred[0] - 2 : 0)); + + j = 10; + for (i = 1; i < nstates; i++) + { + if (j < 10) + ++j; + else + { + output_newline(); + j = 1; + } + + output_int((defred[i] ? defred[i] - 2 : 0)); + } + + end_table(); +} + +static void +token_actions(void) +{ + int i, j; + Value_t shiftcount, reducecount; + int max, min; + Value_t *actionrow, *r, *s; + action *p; + + actionrow = NEW2(2 * ntokens, Value_t); + for (i = 0; i < nstates; ++i) + { + if (parser[i]) + { + for (j = 0; j < 2 * ntokens; ++j) + actionrow[j] = 0; + + shiftcount = 0; + reducecount = 0; + for (p = parser[i]; p; p = p->next) + { + if (p->suppressed == 0) + { + if (p->action_code == SHIFT) + { + ++shiftcount; + actionrow[p->symbol] = p->number; + } + else if (p->action_code == REDUCE && p->number != defred[i]) + { + ++reducecount; + actionrow[p->symbol + ntokens] = p->number; + } + } + } + + tally[i] = shiftcount; + tally[nstates + i] = reducecount; + width[i] = 0; + width[nstates + i] = 0; + if (shiftcount > 0) + { + froms[i] = r = NEW2(shiftcount, Value_t); + tos[i] = s = NEW2(shiftcount, Value_t); + min = MAXSHORT; + max = 0; + for (j = 0; j < ntokens; ++j) + { + if (actionrow[j]) + { + if (min > symbol_value[j]) + min = symbol_value[j]; + if (max < symbol_value[j]) + max = symbol_value[j]; + *r++ = symbol_value[j]; + *s++ = actionrow[j]; + } + } + width[i] = (Value_t) (max - min + 1); + } + if (reducecount > 0) + { + froms[nstates + i] = r = NEW2(reducecount, Value_t); + tos[nstates + i] = s = NEW2(reducecount, Value_t); + min = MAXSHORT; + max = 0; + for (j = 0; j < ntokens; ++j) + { + if (actionrow[ntokens + j]) + { + if (min > symbol_value[j]) + min = symbol_value[j]; + if (max < symbol_value[j]) + max = symbol_value[j]; + *r++ = symbol_value[j]; + *s++ = (Value_t) (actionrow[ntokens + j] - 2); + } + } + width[nstates + i] = (Value_t) (max - min + 1); + } + } + } + FREE(actionrow); +} + +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]; + + if (m == n) + return (0); + + for (i = 0; i < nstates; i++) + state_count[i] = 0; + + for (i = m; i < n; i++) + state_count[to_state[i]]++; + + max = 0; + default_state = 0; + for (i = 0; i < nstates; i++) + { + if (state_count[i] > max) + { + max = state_count[i]; + default_state = i; + } + } + + return (default_state); +} + +static void +save_column(int symbol, int default_state) +{ + int i; + int m; + int n; + Value_t *sp; + Value_t *sp1; + Value_t *sp2; + Value_t count; + int symno; + + m = goto_map[symbol]; + n = goto_map[symbol + 1]; + + count = 0; + for (i = m; i < n; i++) + { + if (to_state[i] != default_state) + ++count; + } + if (count == 0) + return; + + symno = symbol_value[symbol] + 2 * nstates; + + froms[symno] = sp1 = sp = NEW2(count, Value_t); + tos[symno] = sp2 = NEW2(count, Value_t); + + for (i = m; i < n; i++) + { + if (to_state[i] != default_state) + { + *sp1++ = from_state[i]; + *sp2++ = to_state[i]; + } + } + + tally[symno] = count; + width[symno] = (Value_t) (sp1[-1] - sp[0] + 1); +} + +static void +goto_actions(void) +{ + int i, j, k; + + state_count = NEW2(nstates, Value_t); + + k = default_goto(start_symbol + 1); + start_int_table("dgoto", k); + save_column(start_symbol + 1, k); + + j = 10; + for (i = start_symbol + 2; i < nsyms; i++) + { + if (j >= 10) + { + output_newline(); + j = 1; + } + else + ++j; + + k = default_goto(i); + output_int(k); + save_column(i, k); + } + + end_table(); + FREE(state_count); +} + +static void +sort_actions(void) +{ + Value_t i; + int j; + int k; + int t; + int w; + + order = NEW2(nvectors, Value_t); + nentries = 0; + + for (i = 0; i < nvectors; i++) + { + if (tally[i] > 0) + { + t = tally[i]; + w = width[i]; + j = nentries - 1; + + while (j >= 0 && (width[order[j]] < w)) + 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]; + + order[j + 1] = i; + nentries++; + } + } +} + +/* The function matching_vector determines if the vector specified by */ +/* the input parameter matches a previously considered vector. The */ +/* test at the start of the function checks if the vector represents */ +/* a row of shifts over terminal symbols or a row of reductions, or a */ +/* column of shifts over a nonterminal symbol. Berkeley Yacc does not */ +/* check if a column of shifts over a nonterminal symbols matches a */ +/* previously considered vector. Because of the nature of LR parsing */ +/* tables, no two columns can match. Therefore, the only possible */ +/* match would be between a row and a column. Such matches are */ +/* unlikely. Therefore, to save time, no attempt is made to see if a */ +/* column matches a previously considered vector. */ +/* */ +/* Matching_vector is poorly designed. The test could easily be made */ +/* faster. Also, it depends on the vectors being in a specific */ +/* order. */ + +static int +matching_vector(int vector) +{ + int i; + int j; + int k; + int t; + int w; + int match; + int prev; + + i = order[vector]; + if (i >= 2 * nstates) + return (-1); + + t = tally[i]; + w = width[i]; + + for (prev = vector - 1; prev >= 0; prev--) + { + j = order[prev]; + 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 (match) + return (j); + } + + return (-1); +} + +static int +pack_vector(int vector) +{ + int i, j, k, l; + int t; + int loc; + int ok; + Value_t *from; + Value_t *to; + int newmax; + + i = order[vector]; + t = tally[i]; + assert(t); + + from = froms[i]; + to = tos[i]; + + j = lowzero - from[0]; + for (k = 1; k < t; ++k) + if (lowzero - from[k] > j) + j = lowzero - from[k]; + for (;; ++j) + { + if (j == 0) + continue; + ok = 1; + for (k = 0; ok && k < t; k++) + { + loc = j + from[k]; + if (loc >= maxtable - 1) + { + if (loc >= MAXTABLE - 1) + fatal("maximum table size exceeded"); + + newmax = maxtable; + do + { + newmax += 200; + } + while (newmax <= loc); + + table = (Value_t *) REALLOC(table, (unsigned)newmax * sizeof(Value_t)); + NO_SPACE(table); + + check = (Value_t *) REALLOC(check, (unsigned)newmax * sizeof(Value_t)); + NO_SPACE(check); + + for (l = maxtable; l < newmax; ++l) + { + table[l] = 0; + check[l] = -1; + } + maxtable = newmax; + } + + if (check[loc] != -1) + ok = 0; + } + for (k = 0; ok && k < vector; k++) + { + if (pos[k] == j) + ok = 0; + } + if (ok) + { + for (k = 0; k < t; k++) + { + loc = j + from[k]; + table[loc] = to[k]; + check[loc] = from[k]; + if (loc > high) + high = loc; + } + + while (check[lowzero] != -1) + ++lowzero; + + return (j); + } + } +} + +static void +pack_table(void) +{ + int i; + Value_t place; + int state; + + base = NEW2(nvectors, Value_t); + pos = NEW2(nentries, Value_t); + + maxtable = 1000; + table = NEW2(maxtable, Value_t); + check = NEW2(maxtable, Value_t); + + lowzero = 0; + high = 0; + + for (i = 0; i < maxtable; i++) + check[i] = -1; + + for (i = 0; i < nentries; i++) + { + state = matching_vector(i); + + if (state < 0) + place = (Value_t) pack_vector(i); + else + place = base[state]; + + pos[i] = place; + base[order[i]] = place; + } + + for (i = 0; i < nvectors; i++) + { + if (froms[i]) + FREE(froms[i]); + if (tos[i]) + FREE(tos[i]); + } + + FREE(froms); + FREE(tos); + FREE(pos); +} + +static void +output_base(void) +{ + int i, j; + + start_int_table("sindex", base[0]); + + j = 10; + for (i = 1; i < nstates; i++) + { + if (j >= 10) + { + output_newline(); + j = 1; + } + else + ++j; + + output_int(base[i]); + } + + end_table(); + + start_int_table("rindex", base[nstates]); + + j = 10; + for (i = nstates + 1; i < 2 * nstates; i++) + { + if (j >= 10) + { + output_newline(); + j = 1; + } + else + ++j; + + output_int(base[i]); + } + + end_table(); + + start_int_table("gindex", base[2 * nstates]); + + j = 10; + for (i = 2 * nstates + 1; i < nvectors - 1; i++) + { + if (j >= 10) + { + output_newline(); + j = 1; + } + else + ++j; + + output_int(base[i]); + } + + end_table(); + FREE(base); +} + +static void +output_table(void) +{ + int i; + int j; + + ++outline; + fprintf(code_file, "#define YYTABLESIZE %d\n", high); + start_int_table("table", table[0]); + + j = 10; + for (i = 1; i <= high; i++) + { + if (j >= 10) + { + output_newline(); + j = 1; + } + else + ++j; + + output_int(table[i]); + } + + end_table(); + FREE(table); +} + +static void +output_check(void) +{ + int i; + int j; + + start_int_table("check", check[0]); + + j = 10; + for (i = 1; i <= high; i++) + { + if (j >= 10) + { + output_newline(); + j = 1; + } + else + ++j; + + output_int(check[i]); + } + + end_table(); + FREE(check); +} + +static void +output_actions(void) +{ + nvectors = 2 * nstates + nvars; + + froms = NEW2(nvectors, Value_t *); + tos = NEW2(nvectors, Value_t *); + tally = NEW2(nvectors, Value_t); + width = NEW2(nvectors, Value_t); + + token_actions(); + FREE(lookaheads); + FREE(LA); + FREE(LAruleno); + FREE(accessing_symbol); + + goto_actions(); + FREE(goto_map + ntokens); + FREE(from_state); + FREE(to_state); + + sort_actions(); + pack_table(); + output_base(); + output_table(); + output_check(); +} + +static int +is_C_identifier(char *name) +{ + char *s; + int c; + + s = name; + c = *s; + if (c == '"') + { + c = *++s; + if (!isalpha(c) && c != '_' && c != '$') + return (0); + while ((c = *++s) != '"') + { + if (!isalnum(c) && c != '_' && c != '$') + return (0); + } + return (1); + } + + if (!isalpha(c) && c != '_' && c != '$') + return (0); + while ((c = *++s) != 0) + { + if (!isalnum(c) && c != '_' && c != '$') + return (0); + } + return (1); +} + +static void +output_defines(FILE * fp) +{ + int c, i; + char *s; + + for (i = 2; i < ntokens; ++i) + { + s = symbol_name[i]; + if (is_C_identifier(s) && (!sflag || *s != '"')) + { + fprintf(fp, "#define "); + c = *s; + if (c == '"') + { + while ((c = *++s) != '"') + { + putc(c, fp); + } + } + else + { + do + { + putc(c, fp); + } + while ((c = *++s) != 0); + } + if (fp == code_file) + ++outline; + fprintf(fp, " %d\n", symbol_value[i]); + } + } + + if (fp == code_file) + ++outline; + if (fp != defines_file || iflag) + fprintf(fp, "#define YYERRCODE %d\n", symbol_value[1]); + + if (fp == defines_file || (iflag && !dflag)) + { + if (unionized) + { + rewind(union_file); + while ((c = getc(union_file)) != EOF) + putc(c, fp); + fprintf(fp, "extern YYSTYPE %slval;\n", symbol_prefix); + } + } +} + +static void +output_stored_text(FILE * fp) +{ + int c; + FILE *in; + + rewind(text_file); + if (text_file == NULL) + open_error("text_file"); + in = text_file; + if ((c = getc(in)) == EOF) + return; + putc_code(fp, c); + while ((c = getc(in)) != EOF) + { + putc_code(fp, c); + } + write_code_lineno(fp); +} + +static void +output_debug(void) +{ + int i, j, k, max; + const char **symnam; + const char *s; + + ++outline; + fprintf(code_file, "#define YYFINAL %d\n", final_state); + + putl_code(code_file, "#ifndef YYDEBUG\n"); + ++outline; + fprintf(code_file, "#define YYDEBUG %d\n", tflag); + putl_code(code_file, "#endif\n"); + + if (rflag) + { + fprintf(output_file, "#ifndef YYDEBUG\n"); + fprintf(output_file, "#define YYDEBUG %d\n", tflag); + fprintf(output_file, "#endif\n"); + } + + max = 0; + for (i = 2; i < ntokens; ++i) + if (symbol_value[i] > max) + max = symbol_value[i]; + + ++outline; + fprintf(code_file, "#define YYMAXTOKEN %d\n", max); + + symnam = (const char **)MALLOC((unsigned)(max + 1) * sizeof(char *)); + NO_SPACE(symnam); + + /* Note that it is not necessary to initialize the element */ + /* symnam[max]. */ + for (i = 0; i < max; ++i) + symnam[i] = 0; + for (i = ntokens - 1; i >= 2; --i) + symnam[symbol_value[i]] = symbol_name[i]; + symnam[0] = "end-of-file"; + + output_line("#if YYDEBUG"); + + start_str_table("name"); + j = 80; + for (i = 0; i <= max; ++i) + { + if ((s = symnam[i]) != 0) + { + if (s[0] == '"') + { + k = 7; + while (*++s != '"') + { + ++k; + if (*s == '\\') + { + k += 2; + if (*++s == '\\') + ++k; + } + } + j += k; + if (j > 80) + { + output_newline(); + j = k; + } + fprintf(output_file, "\"\\\""); + s = symnam[i]; + while (*++s != '"') + { + if (*s == '\\') + { + fprintf(output_file, "\\\\"); + if (*++s == '\\') + fprintf(output_file, "\\\\"); + else + putc(*s, output_file); + } + else + putc(*s, output_file); + } + fprintf(output_file, "\\\"\","); + } + else if (s[0] == '\'') + { + if (s[1] == '"') + { + j += 7; + if (j > 80) + { + output_newline(); + j = 7; + } + fprintf(output_file, "\"'\\\"'\","); + } + else + { + k = 5; + while (*++s != '\'') + { + ++k; + if (*s == '\\') + { + k += 2; + if (*++s == '\\') + ++k; + } + } + j += k; + if (j > 80) + { + output_newline(); + j = k; + } + fprintf(output_file, "\"'"); + s = symnam[i]; + while (*++s != '\'') + { + if (*s == '\\') + { + fprintf(output_file, "\\\\"); + if (*++s == '\\') + fprintf(output_file, "\\\\"); + else + putc(*s, output_file); + } + else + putc(*s, output_file); + } + fprintf(output_file, "'\","); + } + } + else + { + k = (int)strlen(s) + 3; + j += k; + if (j > 80) + { + output_newline(); + j = k; + } + putc('"', output_file); + do + { + putc(*s, output_file); + } + while (*++s); + fprintf(output_file, "\","); + } + } + else + { + j += 2; + if (j > 80) + { + output_newline(); + j = 2; + } + fprintf(output_file, "0,"); + } + } + end_table(); + FREE(symnam); + + start_str_table("rule"); + for (i = 2; i < nrules; ++i) + { + fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]); + for (j = rrhs[i]; ritem[j] > 0; ++j) + { + s = symbol_name[ritem[j]]; + if (s[0] == '"') + { + fprintf(output_file, " \\\""); + while (*++s != '"') + { + if (*s == '\\') + { + if (s[1] == '\\') + fprintf(output_file, "\\\\\\\\"); + else + fprintf(output_file, "\\\\%c", s[1]); + ++s; + } + else + putc(*s, output_file); + } + fprintf(output_file, "\\\""); + } + else if (s[0] == '\'') + { + if (s[1] == '"') + fprintf(output_file, " '\\\"'"); + else if (s[1] == '\\') + { + if (s[2] == '\\') + fprintf(output_file, " '\\\\\\\\"); + else + fprintf(output_file, " '\\\\%c", s[2]); + s += 2; + while (*++s != '\'') + putc(*s, output_file); + putc('\'', output_file); + } + else + fprintf(output_file, " '%c'", s[1]); + } + else + fprintf(output_file, " %s", s); + } + fprintf(output_file, "\","); + output_newline(); + } + + end_table(); + output_line("#endif"); +} + +static void +output_pure_parser(FILE * fp) +{ + putc_code(fp, '\n'); + + if (fp == code_file) + outline += 1; + fprintf(fp, "#define YYPURE %d\n", pure_parser); + putc_code(fp, '\n'); +} + +static void +output_stype(FILE * fp) +{ + if (!unionized && ntags == 0) + { + putc_code(fp, '\n'); + putl_code(fp, "#ifndef YYSTYPE\n"); + putl_code(fp, "typedef int YYSTYPE;\n"); + putl_code(fp, "#endif\n"); + } +} + +static void +output_trailing_text(void) +{ + int c, last; + FILE *in; + + if (line == 0) + return; + + in = input_file; + c = *cptr; + if (c == '\n') + { + ++lineno; + if ((c = getc(in)) == EOF) + return; + write_input_lineno(); + putc_code(code_file, c); + last = c; + } + else + { + write_input_lineno(); + do + { + putc_code(code_file, c); + } + while ((c = *++cptr) != '\n'); + putc_code(code_file, c); + last = '\n'; + } + + while ((c = getc(in)) != EOF) + { + putc_code(code_file, c); + last = c; + } + + if (last != '\n') + { + putc_code(code_file, '\n'); + } + write_code_lineno(code_file); +} + +static void +output_semantic_actions(void) +{ + int c, last; + + rewind(action_file); + if ((c = getc(action_file)) == EOF) + return; + + last = c; + putc_code(code_file, c); + while ((c = getc(action_file)) != EOF) + { + putc_code(code_file, c); + last = c; + } + + if (last != '\n') + { + putc_code(code_file, '\n'); + } + + write_code_lineno(code_file); +} + +static void +output_parse_decl(FILE * fp) +{ + putl_code(fp, "\n"); + putl_code(fp, "/* compatibility with bison */\n"); + putl_code(fp, "#ifdef YYPARSE_PARAM\n"); + putl_code(fp, "/* compatibility with FreeBSD */\n"); + putl_code(fp, "# ifdef YYPARSE_PARAM_TYPE\n"); + putl_code(fp, + "# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)\n"); + putl_code(fp, "# else\n"); + putl_code(fp, "# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)\n"); + putl_code(fp, "# endif\n"); + putl_code(fp, "#else\n"); + + puts_code(fp, "# define YYPARSE_DECL() yyparse("); + if (!parse_param) + puts_code(fp, "void"); + else + { + param *p; + for (p = parse_param; p; p = p->next) + fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2, + p->next ? ", " : ""); + } + putl_code(fp, ")\n"); + + putl_code(fp, "#endif\n"); +} + +static void +output_lex_decl(FILE * fp) +{ + putl_code(fp, "\n"); + putl_code(fp, "/* Parameters sent to lex. */\n"); + putl_code(fp, "#ifdef YYLEX_PARAM\n"); + if (pure_parser) + { + putl_code(fp, "# ifdef YYLEX_PARAM_TYPE\n"); + putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval," + " YYLEX_PARAM_TYPE YYLEX_PARAM)\n"); + putl_code(fp, "# else\n"); + putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval," + " void * YYLEX_PARAM)\n"); + putl_code(fp, "# endif\n"); + putl_code(fp, "# define YYLEX yylex(&yylval, YYLEX_PARAM)\n"); + } + else + { + putl_code(fp, "# define YYLEX_DECL() yylex(void *YYLEX_PARAM)\n"); + putl_code(fp, "# define YYLEX yylex(YYLEX_PARAM)\n"); + } + putl_code(fp, "#else\n"); + if (pure_parser && lex_param) + { + param *p; + puts_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval, "); + for (p = lex_param; p; p = p->next) + fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2, + p->next ? ", " : ""); + putl_code(fp, ")\n"); + + puts_code(fp, "# define YYLEX yylex(&yylval, "); + for (p = lex_param; p; p = p->next) + fprintf(fp, "%s%s", p->name, p->next ? ", " : ""); + putl_code(fp, ")\n"); + } + else if (pure_parser) + { + putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval)\n"); + putl_code(fp, "# define YYLEX yylex(&yylval)\n"); + } + else if (lex_param) + { + param *p; + puts_code(fp, "# define YYLEX_DECL() yylex("); + for (p = lex_param; p; p = p->next) + fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2, + p->next ? ", " : ""); + putl_code(fp, ")\n"); + + puts_code(fp, "# define YYLEX yylex("); + for (p = lex_param; p; p = p->next) + fprintf(fp, "%s%s", p->name, p->next ? ", " : ""); + putl_code(fp, ")\n"); + } + else + { + putl_code(fp, "# define YYLEX_DECL() yylex(void)\n"); + putl_code(fp, "# define YYLEX yylex()\n"); + } + putl_code(fp, "#endif\n"); +} + +static void +output_error_decl(FILE * fp) +{ + putl_code(fp, "\n"); + putl_code(fp, "/* Parameters sent to yyerror. */\n"); + if (parse_param) + { + param *p; + + putl_code(fp, "#ifndef YYERROR_DECL\n"); + fprintf(fp, "#define YYERROR_DECL() yyerror("); + for (p = parse_param; p; p = p->next) + fprintf(fp, "%s %s%s, ", p->type, p->name, p->type2); + putl_code(fp, "const char *s)\n"); + putl_code(fp, "#endif\n"); + + putl_code(fp, "#ifndef YYERROR_CALL\n"); + puts_code(fp, "#define YYERROR_CALL(msg) yyerror("); + + for (p = parse_param; p; p = p->next) + fprintf(fp, "%s, ", p->name); + + putl_code(fp, "msg)\n"); + putl_code(fp, "#endif\n"); + } + else + { + putl_code(fp, "#ifndef YYERROR_DECL\n"); + putl_code(fp, "#define YYERROR_DECL() yyerror(const char *s)\n"); + putl_code(fp, "#endif\n"); + putl_code(fp, "#ifndef YYERROR_CALL\n"); + putl_code(fp, "#define YYERROR_CALL(msg) yyerror(msg)\n"); + putl_code(fp, "#endif\n"); + } +} + +static void +free_itemsets(void) +{ + core *cp, *next; + + FREE(state_table); + for (cp = first_state; cp; cp = next) + { + next = cp->next; + FREE(cp); + } +} + +static void +free_shifts(void) +{ + shifts *sp, *next; + + FREE(shift_table); + for (sp = first_shift; sp; sp = next) + { + next = sp->next; + FREE(sp); + } +} + +static void +free_reductions(void) +{ + reductions *rp, *next; + + FREE(reduction_table); + for (rp = first_reduction; rp; rp = next) + { + next = rp->next; + FREE(rp); + } +} + +static void +output_yyerror_call(const char *msg) +{ + FILE *fp = code_file; + + puts_code(fp, " yyerror("); + if (parse_param) + { + param *p; + for (p = parse_param; p; p = p->next) + fprintf(fp, "%s, ", p->name); + } + puts_code(fp, "\""); + puts_code(fp, msg); + putl_code(fp, "\");\n"); +} + +static void +output_externs(FILE * fp, const char *const section[]) +{ + int c; + int i; + const char *s; + + for (i = 0; (s = section[i]) != 0; ++i) + { + if (*s && *s != '#') + fputs("extern\t", fp); + while ((c = *s) != 0) + { + putc(c, fp); + ++s; + } + if (fp == code_file) + ++outline; + putc('\n', fp); + } +} + +void +output(void) +{ + FILE *fp; + + free_itemsets(); + free_shifts(); + free_reductions(); + + if (iflag) + { + ++outline; + fprintf(code_file, "#include \"%s\"\n", externs_file_name); + fp = externs_file; + } + else + fp = code_file; + + output_prefix(iflag ? externs_file : output_file); + output_pure_parser(fp); + output_stored_text(fp); + output_stype(fp); + output_parse_decl(fp); + output_lex_decl(fp); + output_error_decl(fp); + write_section(fp, xdecls); + + if (iflag) + { + output_externs(externs_file, global_vars); + if (!pure_parser) + output_externs(externs_file, impure_vars); + } + + if (iflag) + { + ++outline; + fprintf(code_file, "#include \"%s\"\n", defines_file_name); + if (!dflag) + output_defines(externs_file); + } + else + { + putc_code(code_file, '\n'); + output_defines(code_file); + } + + if (dflag) + output_defines(defines_file); + + output_rule_data(); + output_yydefred(); + output_actions(); + free_parser(); + output_debug(); + if (rflag) + { + output_prefix(code_file); + write_section(code_file, xdecls); + write_section(code_file, tables); + } + write_section(code_file, global_vars); + if (!pure_parser) + { + write_section(code_file, impure_vars); + } + write_section(code_file, hdr_defs); + if (!pure_parser) + { + write_section(code_file, hdr_vars); + } + output_trailing_text(); + write_section(code_file, body_1); + if (pure_parser) + { + write_section(code_file, body_vars); + } + write_section(code_file, body_2); + output_yyerror_call("syntax error"); + write_section(code_file, body_3); + output_semantic_actions(); + write_section(code_file, trailer); + output_yyerror_call("yacc stack overflow"); + write_section(code_file, trailer_2); +} + +#ifdef NO_LEAKS +void +output_leaks(void) +{ + DO_FREE(tally); + DO_FREE(width); + DO_FREE(order); +} +#endif |