Imported Upstream version 20101127
[platform/upstream/byacc.git] / output.c
index 51bf59d..eaa2834 100644 (file)
--- a/output.c
+++ b/output.c
@@ -1,8 +1,9 @@
-/* $Id: output.c,v 1.24 2010/02/17 01:48:22 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;
@@ -21,43 +22,64 @@ static int lowzero;
 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);
 }
 
@@ -91,7 +113,8 @@ output_prefix(FILE * fp)
        define_prefixed(fp, "yyname");
        define_prefixed(fp, "yyrule");
     }
-    ++outline;
+    if (CountLine(fp))
+       ++outline;
     fprintf(fp, "#define YYPREFIX \"%s\"\n", symbol_prefix);
 }
 
@@ -532,12 +555,13 @@ pack_vector(int vector)
                    newmax += 200;
                }
                while (newmax <= loc);
+
                table = (Value_t *) REALLOC(table, (unsigned)newmax * sizeof(Value_t));
-               if (table == 0)
-                   no_space();
+               NO_SPACE(table);
+
                check = (Value_t *) REALLOC(check, (unsigned)newmax * sizeof(Value_t));
-               if (check == 0)
-                   no_space();
+               NO_SPACE(check);
+
                for (l = maxtable; l < newmax; ++l)
                {
                    table[l] = 0;
@@ -804,7 +828,7 @@ output_defines(void)
        s = symbol_name[i];
        if (is_C_identifier(s))
        {
-           fprintf(code_file, "#define ");
+           puts_code("#define ");
            if (dflag)
                fprintf(defines_file, "#define ");
            c = *s;
@@ -842,7 +866,7 @@ output_defines(void)
        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);
     }
 }
@@ -851,7 +875,7 @@ static void
 output_stored_text(void)
 {
     int c;
-    FILE *in, *out;
+    FILE *in;
 
     rewind(text_file);
     if (text_file == NULL)
@@ -859,13 +883,12 @@ output_stored_text(void)
     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
@@ -878,8 +901,10 @@ output_debug(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)
     {
@@ -897,8 +922,7 @@ output_debug(void)
     fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
 
     symnam = (const char **)MALLOC((unsigned)(max + 1) * sizeof(char *));
-    if (symnam == 0)
-       no_space();
+    NO_SPACE(symnam);
 
     /* Note that it is  not necessary to initialize the element         */
     /* symnam[max].                                                     */
@@ -1090,8 +1114,12 @@ output_debug(void)
 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
@@ -1099,8 +1127,11 @@ output_stype(void)
 {
     if (!unionized && ntags == 0)
     {
-       outline += 3;
-       fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n");
+       putc_code('\n');
+       putl_code("#ifndef YYSTYPE\n");
+       putl_code("typedef int YYSTYPE;\n");
+       putl_code("#endif\n");
+       putc_code('\n');
     }
 }
 
@@ -1108,73 +1139,183 @@ static void
 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();
+}
+
+static void
+output_parse_decl(void)
+{
+    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)
+       puts_code("void");
+    else
+    {
+       param *p;
+       for (p = parse_param; p; p = p->next)
+           fprintf(code_file, "%s %s%s%s", p->type, p->name, p->type2,
+                   p->next ? ", " : "");
+    }
+    putl_code(")\n");
+
+    putl_code("#endif\n");
+    putl_code("\n");
+}
+
+static void
+output_lex_decl(void)
+{
+    putl_code("/* Parameters sent to lex. */\n");
+    putl_code("#ifdef YYLEX_PARAM\n");
+    if (pure_parser)
+    {
+       putl_code("# define YYLEX_DECL() yylex(YYSTYPE *yylval, "
+                 "void *YYLEX_PARAM)\n");
+       putl_code("# define YYLEX yylex(&yylval, YYLEX_PARAM)\n");
+    }
+    else
+    {
+       putl_code("# define YYLEX_DECL() yylex(void *YYLEX_PARAM)\n");
+       putl_code("# define YYLEX yylex(YYLEX_PARAM)\n");
+    }
+    putl_code("#else\n");
+    if (pure_parser && lex_param)
+    {
+       param *p;
+       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 ? ", " : "");
+       putl_code(")\n");
+
+       puts_code("# define YYLEX yylex(&yylval, ");
+       for (p = lex_param; p; p = p->next)
+           fprintf(code_file, "%s%s", p->name, p->next ? ", " : "");
+       putl_code(")\n");
+    }
+    else if (pure_parser)
+    {
+       putl_code("# define YYLEX_DECL() yylex(YYSTYPE *yylval)\n");
+       putl_code("# define YYLEX yylex(&yylval)\n");
+    }
+    else if (lex_param)
+    {
+       param *p;
+       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 ? ", " : "");
+       putl_code(")\n");
+
+       puts_code("# define YYLEX yylex(");
+       for (p = lex_param; p; p = p->next)
+           fprintf(code_file, "%s%s", p->name, p->next ? ", " : "");
+       putl_code(")\n");
+    }
+    else
+    {
+       putl_code("# define YYLEX_DECL() yylex(void)\n");
+       putl_code("# define YYLEX yylex()\n");
     }
+    putl_code("#endif\n");
+    putl_code("\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(");
 
-    write_code_lineno(out);
+       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");
+    }
+    putl_code("\n");
 }
 
 static void
@@ -1216,6 +1357,21 @@ free_reductions(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)
 {
@@ -1223,15 +1379,19 @@ output(void)
     free_shifts();
     free_reductions();
     output_prefix(output_file);
-    write_section(xdecls);
+    output_pure_parser();
     output_stored_text();
+    output_stype();
+    output_parse_decl();
+    output_lex_decl();
+    output_error_decl();
+    write_section(xdecls);
     output_defines();
     output_rule_data();
     output_yydefred();
     output_actions();
     free_parser();
     output_debug();
-    output_stype();
     if (rflag)
     {
        output_prefix(code_file);
@@ -1239,7 +1399,6 @@ output(void)
        write_section(tables);
     }
     write_section(hdr_defs);
-    output_pure_parser();
     if (!pure_parser)
     {
        write_section(hdr_vars);
@@ -1251,8 +1410,12 @@ output(void)
        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