Imported Upstream version 20170430
[platform/upstream/byacc.git] / output.c
index eb4402d..d52d920 100644 (file)
--- a/output.c
+++ b/output.c
@@ -1,4 +1,4 @@
-/* $Id: output.c,v 1.67 2014/04/22 23:16:57 tom Exp $ */
+/* $Id: output.c,v 1.81 2017/04/30 23:23:32 tom Exp $ */
 
 #include "defs.h"
 
@@ -54,6 +54,43 @@ puts_code(FILE * fp, const char *s)
 }
 
 static void
+puts_param_types(FILE * fp, param *list, int more)
+{
+    param *p;
+
+    if (list != 0)
+    {
+       for (p = list; p; p = p->next)
+       {
+           size_t len_type = strlen(p->type);
+           fprintf(fp, "%s%s%s%s%s", p->type,
+                   (((len_type != 0) && (p->type[len_type - 1] == '*'))
+                    ? ""
+                    : " "),
+                   p->name, p->type2,
+                   ((more || p->next) ? ", " : ""));
+       }
+    }
+    else
+    {
+       if (!more)
+           fprintf(fp, "void");
+    }
+}
+
+static void
+puts_param_names(FILE * fp, param *list, int more)
+{
+    param *p;
+
+    for (p = list; p; p = p->next)
+    {
+       fprintf(fp, "%s%s", p->name,
+               ((more || p->next) ? ", " : ""));
+    }
+}
+
+static void
 write_code_lineno(FILE * fp)
 {
     if (!lflag && (fp == code_file))
@@ -198,6 +235,43 @@ end_table(void)
 }
 
 static void
+output_stype(FILE * fp)
+{
+    if (!unionized && ntags == 0)
+    {
+       putc_code(fp, '\n');
+       putl_code(fp, "#if "
+                 "! defined(YYSTYPE) && "
+                 "! defined(YYSTYPE_IS_DECLARED)\n");
+       putl_code(fp, "/* Default: YYSTYPE is the semantic value type. */\n");
+       putl_code(fp, "typedef int YYSTYPE;\n");
+       putl_code(fp, "# define YYSTYPE_IS_DECLARED 1\n");
+       putl_code(fp, "#endif\n");
+    }
+}
+
+#if defined(YYBTYACC)
+static void
+output_ltype(FILE * fp)
+{
+    putc_code(fp, '\n');
+    putl_code(fp, "#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED\n");
+    putl_code(fp, "/* Default: YYLTYPE is the text position type. */\n");
+    putl_code(fp, "typedef struct YYLTYPE\n");
+    putl_code(fp, "{\n");
+    putl_code(fp, "    int first_line;\n");
+    putl_code(fp, "    int first_column;\n");
+    putl_code(fp, "    int last_line;\n");
+    putl_code(fp, "    int last_column;\n");
+    putl_code(fp, "    unsigned source;\n");
+    putl_code(fp, "} YYLTYPE;\n");
+    putl_code(fp, "#define YYLTYPE_IS_DECLARED 1\n");
+    putl_code(fp, "#endif\n");
+    putl_code(fp, "#define YYRHSLOC(rhs, k) ((rhs)[k])\n");
+}
+#endif
+
+static void
 output_YYINT_typedef(FILE * fp)
 {
     /* generate the type used to index the various parser tables */
@@ -292,6 +366,8 @@ output_accessing_symbols(void)
            translate[i] = symbol_pval[gsymb];
        }
 
+       putl_code(output_file,
+                 "#if defined(YYDESTRUCT_CALL) || defined(YYSTYPE_TOSTRING)\n");
        /* yystos[] may be unused, depending on compile-time defines */
        start_int_table("stos", translate[0]);
 
@@ -311,6 +387,8 @@ output_accessing_symbols(void)
 
        end_table();
        FREE(translate);
+       putl_code(output_file,
+                 "#endif /* YYDESTRUCT_CALL || YYSTYPE_TOSTRING */\n");
     }
 }
 
@@ -329,7 +407,7 @@ find_conflict_base(int cbase)
        if (j + cbase >= nconflicts)
            break;
     }
-    return (Value_t) i;
+    return (Value_t)i;
 }
 #endif
 
@@ -375,7 +453,7 @@ token_actions(void)
                        conflictcount++;
                        conflicts[nconflicts++] = -1;
                        j = find_conflict_base(cbase);
-                       actionrow[csym + 2 * ntokens] = (Value_t) (j + 1);
+                       actionrow[csym + 2 * ntokens] = (Value_t)(j + 1);
                        if (j == cbase)
                        {
                            cbase = nconflicts;
@@ -420,7 +498,7 @@ token_actions(void)
                            else
                                conflicts[nconflicts++] = -1;
                        }
-                       conflicts[nconflicts++] = (Value_t) (p->number - 2);
+                       conflicts[nconflicts++] = (Value_t)(p->number - 2);
                    }
                }
 #endif
@@ -431,7 +509,7 @@ token_actions(void)
                conflictcount++;
                conflicts[nconflicts++] = -1;
                j = find_conflict_base(cbase);
-               actionrow[csym + 2 * ntokens] = (Value_t) (j + 1);
+               actionrow[csym + 2 * ntokens] = (Value_t)(j + 1);
                if (j == cbase)
                {
                    cbase = nconflicts;
@@ -475,7 +553,7 @@ token_actions(void)
                        *s++ = actionrow[j];
                    }
                }
-               width[i] = (Value_t) (max - min + 1);
+               width[i] = (Value_t)(max - min + 1);
            }
            if (reducecount > 0)
            {
@@ -492,10 +570,10 @@ token_actions(void)
                        if (max < symbol_value[j])
                            max = symbol_value[j];
                        *r++ = symbol_value[j];
-                       *s++ = (Value_t) (actionrow[ntokens + j] - 2);
+                       *s++ = (Value_t)(actionrow[ntokens + j] - 2);
                    }
                }
-               width[nstates + i] = (Value_t) (max - min + 1);
+               width[nstates + i] = (Value_t)(max - min + 1);
            }
 #if defined(YYBTYACC)
            if (backtrack && conflictcount > 0)
@@ -513,10 +591,10 @@ token_actions(void)
                        if (max < symbol_value[j])
                            max = symbol_value[j];
                        *r++ = symbol_value[j];
-                       *s++ = (Value_t) (actionrow[2 * ntokens + j] - 1);
+                       *s++ = (Value_t)(actionrow[2 * ntokens + j] - 1);
                    }
                }
-               width[2 * nstates + i] = (Value_t) (max - min + 1);
+               width[2 * nstates + i] = (Value_t)(max - min + 1);
            }
 #endif
        }
@@ -598,7 +676,7 @@ save_column(int symbol, int default_state)
     }
 
     tally[symno] = count;
-    width[symno] = (Value_t) (sp1[-1] - sp[0] + 1);
+    width[symno] = (Value_t)(sp1[-1] - sp[0] + 1);
 }
 
 static void
@@ -834,7 +912,7 @@ pack_table(void)
        state = matching_vector(i);
 
        if (state < 0)
-           place = (Value_t) pack_vector(i);
+           place = (Value_t)pack_vector(i);
        else
            place = base[state];
 
@@ -1007,30 +1085,33 @@ output_ctable(void)
 {
     int i;
     int j;
+    int limit = (conflicts != 0) ? nconflicts : 0;
 
-    if (conflicts)
-    {
-       output_line("#if YYBTYACC");
-       start_int_table("ctable", conflicts[0]);
+    if (limit < high)
+       limit = (int)high;
 
-       j = 10;
-       for (i = 1; i < nconflicts; i++)
-       {
-           if (j >= 10)
-           {
-               output_newline();
-               j = 1;
-           }
-           else
-               ++j;
+    output_line("#if YYBTYACC");
+    start_int_table("ctable", conflicts ? conflicts[0] : -1);
 
-           output_int(conflicts[i]);
+    j = 10;
+    for (i = 1; i < limit; i++)
+    {
+       if (j >= 10)
+       {
+           output_newline();
+           j = 1;
        }
+       else
+           ++j;
 
-       end_table();
-       output_line("#endif");
-       FREE(conflicts);
+       output_int((conflicts != 0 && i < nconflicts) ? conflicts[i] : -1);
     }
+
+    if (conflicts)
+       FREE(conflicts);
+
+    end_table();
+    output_line("#endif");
 }
 #endif
 
@@ -1056,7 +1137,7 @@ output_actions(void)
     FREE(accessing_symbol);
 
     goto_actions();
-    FREE(goto_map + ntokens);
+    FREE(goto_base);
     FREE(from_state);
     FREE(to_state);
 
@@ -1158,6 +1239,16 @@ output_defines(FILE * fp)
     if (fp != defines_file || iflag)
        fprintf(fp, "#define YYERRCODE %d\n", symbol_value[1]);
 
+    if (token_table && rflag && fp != externs_file)
+    {
+       if (fp == code_file)
+           ++outline;
+       fputs("#undef yytname\n", fp);
+       if (fp == code_file)
+           ++outline;
+       fputs("#define yytname yyname\n", fp);
+    }
+
     if (fp == defines_file || (iflag && !dflag))
     {
        if (unionized)
@@ -1170,6 +1261,10 @@ output_defines(FILE * fp)
            }
            fprintf(fp, "extern YYSTYPE %slval;\n", symbol_prefix);
        }
+#if defined(YYBTYACC)
+       if (locations)
+           output_ltype(fp);
+#endif
     }
 }
 
@@ -1267,8 +1362,11 @@ output_debug(void)
      */
     if (token_table)
     {
-       output_line("#undef yytname");
-       output_line("#define yytname yyname");
+       if (!rflag)
+       {
+           output_line("#undef yytname");
+           output_line("#define yytname yyname");
+       }
     }
     else
     {
@@ -1486,38 +1584,16 @@ output_pure_parser(FILE * fp)
     putc_code(fp, '\n');
 }
 
+#if defined(YY_NO_LEAKS)
 static void
-output_stype(FILE * fp)
+output_no_leaks(FILE * fp)
 {
-    if (!unionized && ntags == 0)
-    {
-       putc_code(fp, '\n');
-       putl_code(fp, "#if "
-                 "! defined(YYSTYPE) && "
-                 "! defined(YYSTYPE_IS_DECLARED)\n");
-       putl_code(fp, "/* Default: YYSTYPE is the semantic value type. */\n");
-       putl_code(fp, "typedef int YYSTYPE;\n");
-       putl_code(fp, "# define YYSTYPE_IS_DECLARED 1\n");
-       putl_code(fp, "#endif\n");
-    }
-}
+    putc_code(fp, '\n');
 
-#if defined(YYBTYACC)
-static void
-output_ltype(FILE * fp)
-{
+    if (fp == code_file)
+       ++outline;
+    fputs("#define YY_NO_LEAKS 1\n", fp);
     putc_code(fp, '\n');
-    putl_code(fp, "#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED\n");
-    putl_code(fp, "/* Default: YYLTYPE is the text position type. */\n");
-    putl_code(fp, "typedef struct YYLTYPE\n");
-    putl_code(fp, "{\n");
-    putl_code(fp, "    int first_line;\n");
-    putl_code(fp, "    int first_column;\n");
-    putl_code(fp, "    int last_line;\n");
-    putl_code(fp, "    int last_column;\n");
-    putl_code(fp, "} YYLTYPE;\n");
-    putl_code(fp, "#define YYLTYPE_IS_DECLARED 1\n");
-    putl_code(fp, "#endif\n");
 }
 #endif
 
@@ -1607,15 +1683,7 @@ output_parse_decl(FILE * fp)
     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 ? ", " : "");
-    }
+    puts_param_types(fp, parse_param, 0);
     putl_code(fp, ")\n");
 
     putl_code(fp, "#endif\n");
@@ -1633,7 +1701,8 @@ output_lex_decl(FILE * fp)
 #if defined(YYBTYACC)
        if (locations)
        {
-           putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc,"
+           putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
+                     " YYLTYPE *yylloc,"
                      " YYLEX_PARAM_TYPE YYLEX_PARAM)\n");
        }
        else
@@ -1646,7 +1715,8 @@ output_lex_decl(FILE * fp)
 #if defined(YYBTYACC)
        if (locations)
        {
-           putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc,"
+           putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
+                     " YYLTYPE *yylloc,"
                      " void * YYLEX_PARAM)\n");
        }
        else
@@ -1672,8 +1742,6 @@ output_lex_decl(FILE * fp)
     putl_code(fp, "#else\n");
     if (pure_parser && lex_param)
     {
-       param *p;
-
 #if defined(YYBTYACC)
        if (locations)
            puts_code(fp,
@@ -1681,9 +1749,7 @@ output_lex_decl(FILE * fp)
        else
 #endif
            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 ? ", " : "");
+       puts_param_types(fp, lex_param, 0);
        putl_code(fp, ")\n");
 
 #if defined(YYBTYACC)
@@ -1692,8 +1758,7 @@ output_lex_decl(FILE * fp)
        else
 #endif
            puts_code(fp, "# define YYLEX yylex(&yylval, ");
-       for (p = lex_param; p; p = p->next)
-           fprintf(fp, "%s%s", p->name, p->next ? ", " : "");
+       puts_param_names(fp, lex_param, 0);
        putl_code(fp, ")\n");
     }
     else if (pure_parser)
@@ -1714,17 +1779,12 @@ output_lex_decl(FILE * fp)
     }
     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 ? ", " : "");
+       puts_param_types(fp, lex_param, 0);
        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 ? ", " : "");
+       puts_param_names(fp, lex_param, 0);
        putl_code(fp, ")\n");
     }
     else
@@ -1738,32 +1798,28 @@ output_lex_decl(FILE * fp)
 static void
 output_error_decl(FILE * fp)
 {
-    param *p;
-
     putc_code(fp, '\n');
     putl_code(fp, "/* Parameters sent to yyerror. */\n");
     putl_code(fp, "#ifndef YYERROR_DECL\n");
     puts_code(fp, "#define YYERROR_DECL() yyerror(");
 #if defined(YYBTYACC)
     if (locations)
-       puts_code(fp, "YYLTYPE loc, ");
+       puts_code(fp, "YYLTYPE *loc, ");
 #endif
-    for (p = parse_param; p; p = p->next)
-       fprintf(fp, "%s %s%s, ", p->type, p->name, p->type2);
+    puts_param_types(fp, parse_param, 1);
     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(");
 
+    puts_code(fp, "#define YYERROR_CALL(msg) yyerror(");
 #if defined(YYBTYACC)
     if (locations)
-       puts_code(fp, "yylloc, ");
+       puts_code(fp, "&yylloc, ");
 #endif
-    for (p = parse_param; p; p = p->next)
-       fprintf(fp, "%s, ", p->name);
-
+    puts_param_names(fp, parse_param, 1);
     putl_code(fp, "msg)\n");
+
     putl_code(fp, "#endif\n");
 }
 
@@ -1773,28 +1829,53 @@ output_yydestruct_decl(FILE * fp)
 {
     putc_code(fp, '\n');
     putl_code(fp, "#ifndef YYDESTRUCT_DECL\n");
+
+    puts_code(fp,
+             "#define YYDESTRUCT_DECL() "
+             "yydestruct(const char *msg, int psymb, YYSTYPE *val");
 #if defined(YYBTYACC)
     if (locations)
-       putl_code(fp,
-                 "#define YYDESTRUCT_DECL() yydestruct(const char *msg, int psymb, YYSTYPE *val, YYLTYPE *loc)\n");
-    else
+       puts_code(fp, ", YYLTYPE *loc");
 #endif
-       putl_code(fp,
-                 "#define YYDESTRUCT_DECL() yydestruct(const char *msg, int psymb, YYSTYPE *val)\n");
+    if (parse_param)
+    {
+       puts_code(fp, ", ");
+       puts_param_types(fp, parse_param, 0);
+    }
+    putl_code(fp, ")\n");
+
     putl_code(fp, "#endif\n");
+
     putl_code(fp, "#ifndef YYDESTRUCT_CALL\n");
+
+    puts_code(fp, "#define YYDESTRUCT_CALL(msg, psymb, val");
 #if defined(YYBTYACC)
     if (locations)
-       putl_code(fp,
-                 "#define YYDESTRUCT_CALL(msg, psymb, val, loc) yydestruct(msg, psymb, val, loc)\n");
-    else
+       puts_code(fp, ", loc");
 #endif
-       putl_code(fp,
-                 "#define YYDESTRUCT_CALL(msg, psymb, val) yydestruct(msg, psymb, val)\n");
+    puts_code(fp, ") yydestruct(msg, psymb, val");
+#if defined(YYBTYACC)
+    if (locations)
+       puts_code(fp, ", loc");
+#endif
+    if (parse_param)
+    {
+       puts_code(fp, ", ");
+       puts_param_names(fp, parse_param, 0);
+    }
+    putl_code(fp, ")\n");
+
     putl_code(fp, "#endif\n");
 }
 
 static void
+output_initial_action(void)
+{
+    if (initial_action)
+       fprintf(code_file, "%s\n", initial_action);
+}
+
+static void
 output_yydestruct_impl(void)
 {
     int i;
@@ -1917,6 +1998,9 @@ output(void)
 
     output_prefix(fp);
     output_pure_parser(fp);
+#if defined(YY_NO_LEAKS)
+    output_no_leaks(fp);
+#endif
     output_stored_text(fp);
     output_stype(fp);
 #if defined(YYBTYACC)
@@ -2000,6 +2084,15 @@ output(void)
        write_section(code_file, body_vars);
     }
     write_section(code_file, body_2);
+    if (pure_parser)
+    {
+       write_section(code_file, init_vars);
+    }
+#if defined(YYBTYACC)
+    if (initial_action)
+       output_initial_action();
+#endif
+    write_section(code_file, body_3);
     output_semantic_actions();
     write_section(code_file, trailer);
 }