-/* $Id: output.c,v 1.29 2010/06/09 21:25:18 tom Exp $ */
+/* $Id: output.c,v 1.37 2010/11/27 17:28:29 tom Exp $ */
#include "defs.h"
#define StaticOrR (rflag ? "" : "static ")
+#define CountLine(fp) (!rflag || ((fp) == code_file))
static int nvectors;
static int nentries;
static int high;
static void
-write_char(FILE * out, int c)
+putc_code(int c)
{
if (c == '\n')
++outline;
- putc(c, out);
+ putc(c, code_file);
}
static void
-write_code_lineno(FILE * out)
+putl_code(const char *s)
+{
+ ++outline;
+ fputs(s, code_file);
+}
+
+static void
+puts_code(const char *s)
+{
+ fputs(s, code_file);
+}
+
+static void
+write_code_lineno(void)
{
if (!lflag)
- fprintf(out, line_format, (outline++) + 1, code_file_name);
+ {
+ ++outline;
+ fprintf(code_file, line_format, outline, code_file_name);
+ }
}
static void
-write_input_lineno(FILE * out)
+write_input_lineno(void)
{
if (!lflag)
{
++outline;
- fprintf(out, line_format, lineno, input_file_name);
+ fprintf(code_file, line_format, lineno, input_file_name);
}
}
static void
define_prefixed(FILE * fp, const char *name)
{
- ++outline;
+ int bump_line = CountLine(fp);
+ if (bump_line)
+ ++outline;
fprintf(fp, "\n");
- ++outline;
+ if (bump_line)
+ ++outline;
fprintf(fp, "#ifndef %s\n", name);
- ++outline;
+ if (bump_line)
+ ++outline;
fprintf(fp, "#define %-10s %s%s\n", name, symbol_prefix, name + 2);
- ++outline;
+ if (bump_line)
+ ++outline;
fprintf(fp, "#endif /* %s */\n", name);
}
define_prefixed(fp, "yyname");
define_prefixed(fp, "yyrule");
}
- ++outline;
+ if (CountLine(fp))
+ ++outline;
fprintf(fp, "#define YYPREFIX \"%s\"\n", symbol_prefix);
}
s = symbol_name[i];
if (is_C_identifier(s))
{
- fprintf(code_file, "#define ");
+ puts_code("#define ");
if (dflag)
fprintf(defines_file, "#define ");
c = *s;
rewind(union_file);
while ((c = getc(union_file)) != EOF)
putc(c, defines_file);
- fprintf(defines_file, " YYSTYPE;\nextern YYSTYPE %slval;\n",
+ fprintf(defines_file, "extern YYSTYPE %slval;\n",
symbol_prefix);
}
}
output_stored_text(void)
{
int c;
- FILE *in, *out;
+ FILE *in;
rewind(text_file);
if (text_file == NULL)
in = text_file;
if ((c = getc(in)) == EOF)
return;
- out = code_file;
- write_char(out, c);
+ putc_code(c);
while ((c = getc(in)) != EOF)
{
- write_char(out, c);
+ putc_code(c);
}
- write_code_lineno(out);
+ write_code_lineno();
}
static void
++outline;
fprintf(code_file, "#define YYFINAL %d\n", final_state);
- outline += 3;
- fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n", tflag);
+ putl_code("#ifndef YYDEBUG\n");
+ ++outline;
+ fprintf(code_file, "#define YYDEBUG %d\n", tflag);
+ putl_code("#endif\n");
if (rflag)
{
static void
output_pure_parser(void)
{
- outline += 3;
- fprintf(code_file, "\n#define YYPURE %d\n\n", pure_parser);
+ putc_code('\n');
+
+ outline += 1;
+ fprintf(code_file, "#define YYPURE %d\n", pure_parser);
+
+ putc_code('\n');
}
static void
{
if (!unionized && ntags == 0)
{
- outline += 5;
- fprintf(code_file,
- "\n#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n\n");
+ putc_code('\n');
+ putl_code("#ifndef YYSTYPE\n");
+ putl_code("typedef int YYSTYPE;\n");
+ putl_code("#endif\n");
+ putc_code('\n');
}
}
output_trailing_text(void)
{
int c, last;
- FILE *in, *out;
+ FILE *in;
if (line == 0)
return;
in = input_file;
- out = code_file;
c = *cptr;
if (c == '\n')
{
++lineno;
if ((c = getc(in)) == EOF)
return;
- write_input_lineno(out);
- write_char(out, c);
+ write_input_lineno();
+ putc_code(c);
last = c;
}
else
{
- write_input_lineno(out);
+ write_input_lineno();
do
{
- putc(c, out);
+ putc_code(c);
}
while ((c = *++cptr) != '\n');
- write_char(out, c);
+ putc_code(c);
last = '\n';
}
while ((c = getc(in)) != EOF)
{
- write_char(out, c);
+ putc_code(c);
last = c;
}
if (last != '\n')
{
- write_char(out, '\n');
+ putc_code('\n');
}
- write_code_lineno(out);
+ write_code_lineno();
}
static void
output_semantic_actions(void)
{
int c, last;
- FILE *out;
rewind(action_file);
if ((c = getc(action_file)) == EOF)
return;
- out = code_file;
last = c;
- write_char(out, c);
+ putc_code(c);
while ((c = getc(action_file)) != EOF)
{
- write_char(out, c);
+ putc_code(c);
last = c;
}
if (last != '\n')
{
- write_char(out, '\n');
+ putc_code('\n');
}
- write_code_lineno(out);
+ write_code_lineno();
}
static void
output_parse_decl(void)
{
- ++outline;
- fprintf(code_file, "/* compatibility with bison */\n");
- ++outline;
- fprintf(code_file, "#ifdef YYPARSE_PARAM\n");
- ++outline;
- fprintf(code_file, "/* compatibility with FreeBSD */\n");
- ++outline;
- fprintf(code_file, "# ifdef YYPARSE_PARAM_TYPE\n");
- ++outline;
- fprintf(code_file, "# define YYPARSE_DECL() "
- "yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)\n");
- ++outline;
- fprintf(code_file, "# else\n");
- ++outline;
- fprintf(code_file, "# define YYPARSE_DECL() "
- "yyparse(void *YYPARSE_PARAM)\n");
- ++outline;
- fprintf(code_file, "# endif\n");
- ++outline;
- fprintf(code_file, "#else\n");
- ++outline;
- fprintf(code_file, "# define YYPARSE_DECL() yyparse(");
+ putl_code("/* compatibility with bison */\n");
+ putl_code("#ifdef YYPARSE_PARAM\n");
+ putl_code("/* compatibility with FreeBSD */\n");
+ putl_code("# ifdef YYPARSE_PARAM_TYPE\n");
+ putl_code("# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)\n");
+ putl_code("# else\n");
+ putl_code("# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)\n");
+ putl_code("# endif\n");
+ putl_code("#else\n");
+
+ puts_code("# define YYPARSE_DECL() yyparse(");
if (!parse_param)
- fprintf(code_file, "void");
+ puts_code("void");
else
{
param *p;
fprintf(code_file, "%s %s%s%s", p->type, p->name, p->type2,
p->next ? ", " : "");
}
- fprintf(code_file, ")\n");
- outline += 2;
- fprintf(code_file, "#endif\n\n");
+ putl_code(")\n");
+
+ putl_code("#endif\n");
+ putl_code("\n");
}
static void
output_lex_decl(void)
{
- ++outline;
- fprintf(code_file, "/* Parameters sent to lex. */\n");
- ++outline;
- fprintf(code_file, "#ifdef YYLEX_PARAM\n");
+ putl_code("/* Parameters sent to lex. */\n");
+ putl_code("#ifdef YYLEX_PARAM\n");
if (pure_parser)
{
- ++outline;
- fprintf(code_file, "# define YYLEX_DECL() yylex(YYSTYPE *yylval, "
- "void *YYLEX_PARAM)\n");
- ++outline;
- fprintf(code_file, "# define YYLEX yylex(&yylval, YYLEX_PARAM)\n");
+ putl_code("# define YYLEX_DECL() yylex(YYSTYPE *yylval, "
+ "void *YYLEX_PARAM)\n");
+ putl_code("# define YYLEX yylex(&yylval, YYLEX_PARAM)\n");
}
else
{
- ++outline;
- fprintf(code_file,
- "# define YYLEX_DECL() yylex(void *YYLEX_PARAM)\n");
- ++outline;
- fprintf(code_file, "# define YYLEX yylex(YYLEX_PARAM)\n");
+ putl_code("# define YYLEX_DECL() yylex(void *YYLEX_PARAM)\n");
+ putl_code("# define YYLEX yylex(YYLEX_PARAM)\n");
}
- ++outline;
- fprintf(code_file, "#else\n");
+ putl_code("#else\n");
if (pure_parser && lex_param)
{
param *p;
- fprintf(code_file, "# define YYLEX_DECL() yylex(YYSTYPE *yylval, ");
+ puts_code("# define YYLEX_DECL() yylex(YYSTYPE *yylval, ");
for (p = lex_param; p; p = p->next)
fprintf(code_file, "%s %s%s%s", p->type, p->name, p->type2,
p->next ? ", " : "");
- ++outline;
- fprintf(code_file, ")\n");
+ putl_code(")\n");
- fprintf(code_file, "# define YYLEX yylex(&yylval, ");
+ puts_code("# define YYLEX yylex(&yylval, ");
for (p = lex_param; p; p = p->next)
fprintf(code_file, "%s%s", p->name, p->next ? ", " : "");
- ++outline;
- fprintf(code_file, ")\n");
+ putl_code(")\n");
}
else if (pure_parser)
{
- ++outline;
- fprintf(code_file, "# define YYLEX_DECL() yylex(YYSTYPE *yylval)\n");
-
- ++outline;
- fprintf(code_file, "# define YYLEX yylex(&yylval)\n");
+ putl_code("# define YYLEX_DECL() yylex(YYSTYPE *yylval)\n");
+ putl_code("# define YYLEX yylex(&yylval)\n");
}
else if (lex_param)
{
param *p;
- fprintf(code_file, "# define YYLEX_DECL() yylex(");
+ puts_code("# define YYLEX_DECL() yylex(");
for (p = lex_param; p; p = p->next)
fprintf(code_file, "%s %s%s%s", p->type, p->name, p->type2,
p->next ? ", " : "");
- ++outline;
- fprintf(code_file, ")\n");
+ putl_code(")\n");
- fprintf(code_file, "# define YYLEX yylex(");
+ puts_code("# define YYLEX yylex(");
for (p = lex_param; p; p = p->next)
fprintf(code_file, "%s%s", p->name, p->next ? ", " : "");
- ++outline;
- fprintf(code_file, ")\n");
+ putl_code(")\n");
}
else
{
- ++outline;
- fprintf(code_file, "# define YYLEX_DECL() yylex(void)\n");
+ putl_code("# define YYLEX_DECL() yylex(void)\n");
+ putl_code("# define YYLEX yylex()\n");
+ }
+ putl_code("#endif\n");
+ putl_code("\n");
+}
- ++outline;
- fprintf(code_file, "# define YYLEX yylex()\n");
+static void
+output_error_decl(void)
+{
+ putl_code("/* Parameters sent to yyerror. */\n");
+ if (parse_param)
+ {
+ param *p;
+
+ putl_code("#define YYERROR_DECL() yyerror(YYSTYPE *v, const char *s)\n");
+
+ puts_code("#define YYERROR_CALL(msg) yyerror(");
+
+ for (p = parse_param; p; p = p->next)
+ fprintf(code_file, "%s, ", p->name);
+
+ putl_code("msg)\n");
+ }
+ else
+ {
+ putl_code("#define YYERROR_DECL() yyerror(const char *s)\n");
+ putl_code("#define YYERROR_CALL(msg) yyerror(msg)\n");
}
- outline += 2;
- fprintf(code_file, "#endif\n\n");
+ putl_code("\n");
}
static void
}
}
+static void
+output_yyerror_call(const char *msg)
+{
+ puts_code(" yyerror(");
+ if (parse_param)
+ {
+ param *p;
+ for (p = parse_param; p; p = p->next)
+ fprintf(code_file, "%s, ", p->name);
+ }
+ puts_code("\"");
+ puts_code(msg);
+ putl_code("\");\n");
+}
+
void
output(void)
{
output_stype();
output_parse_decl();
output_lex_decl();
+ output_error_decl();
write_section(xdecls);
output_defines();
output_rule_data();
write_section(body_vars);
}
write_section(body_2);
+ output_yyerror_call("syntax error");
+ write_section(body_3);
output_semantic_actions();
write_section(trailer);
+ output_yyerror_call("yacc stack overflow");
+ write_section(trailer_2);
}
#ifdef NO_LEAKS