]> git.saurik.com Git - bison.git/blobdiff - src/output.c
Really add m4sugar to the repo.
[bison.git] / src / output.c
index 60b79790037936f19295230cd0d0481ad6e115d4..702f0cb18bf8f95608f8e0e79013272fb1f8be0f 100644 (file)
@@ -1,5 +1,5 @@
 /* Output the generated parsing program for bison,
-   Copyright 1984, 1986, 1989, 1992, 2000, 2001
+   Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002
    Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
@@ -90,6 +90,7 @@
 
 #include "system.h"
 #include "quotearg.h"
+#include "error.h"
 #include "getargs.h"
 #include "files.h"
 #include "gram.h"
 #include "conflicts.h"
 #include "muscle_tab.h"
 
+/* From lib/readpipe.h.  */
+FILE *readpipe PARAMS ((const char *, ...));
+
+/* From src/scan-skel.l. */
+int skel_lex PARAMS ((void));
+extern FILE *skel_in;
 
 static int nvectors;
 static int nentries;
@@ -125,7 +132,7 @@ static struct obstack format_obstack;
 int error_verbose = 0;
 
 /* Returns the number of lines of S.  */
-static size_t
+size_t
 get_lines_number (const char *s)
 {
   size_t lines = 0;
@@ -503,8 +510,8 @@ token_actions (void)
 | Output the actions to OOUT.  |
 `-----------------------------*/
 
-static void
-actions_output (FILE *out, size_t *line)
+void
+actions_output (FILE *out)
 {
   int rule;
   for (rule = 1; rule < nrules + 1; ++rule)
@@ -523,14 +530,6 @@ actions_output (FILE *out, size_t *line)
        fprintf (out, "{ %s%s }\n    break;\n\n",
                 rules[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 (rules[rule].action);
       }
 }
 
@@ -539,12 +538,12 @@ actions_output (FILE *out, size_t *line)
 | Output the guards to OOUT.  |
 `----------------------------*/
 
-static void
-guards_output (FILE *out, size_t *line)
+void
+guards_output (FILE *out)
 {
   int rule;
   for (rule = 1; rule < nrules + 1; ++rule)
-    if (rules[rule].action)
+    if (rules[rule].guard)
       {
        fprintf (out, "  case %d:\n", rule);
 
@@ -555,14 +554,6 @@ guards_output (FILE *out, size_t *line)
                                   muscle_find ("filename")));
        fprintf (out, "{ %s; }\n    break;\n\n",
                 rules[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 (rules[rule].guard);
       }
 }
 
@@ -571,8 +562,8 @@ guards_output (FILE *out, size_t *line)
 | Output the tokens definition to OOUT.  |
 `---------------------------------------*/
 
-static void
-token_definitions_output (FILE *out, size_t *line)
+void
+token_definitions_output (FILE *out)
 {
   int i;
   for (i = 0; i < ntokens; ++i)
@@ -603,14 +594,10 @@ token_definitions_output (FILE *out, size_t *line)
 
       fprintf (out, "# define %s\t%d\n",
               symbol->tag, number);
-      ++*line;
       if (semantic_parser)
-       {
-         /* FIXME: This is probably wrong, and should be just as
-            above. --akim.  */
-         fprintf (out, "# define T%s\t%d\n", symbol->tag, symbol->value);
-         ++*line;
-       }
+       /* FIXME: This is probably wrong, and should be just as
+          above. --akim.  */
+       fprintf (out, "# define T%s\t%d\n", symbol->tag, symbol->value);
     }
 }
 
@@ -961,123 +948,68 @@ output_actions (void)
 }
 
 \f
-/*------------------------------------------------------------.
-| Copy the parser code from SKEL_FILENAME into OOUT obstack.  |
-| and do the muscle substitution.                             |
-`------------------------------------------------------------*/
-
-static void
-output_parser (const char *skel_filename, FILE *out)
-{
-  int c;
-  FILE *fskel;
-  size_t output_line;
-  size_t skeleton_line;
-
-  fskel = xfopen (skel_filename, "r");
-
-  /* New output code.  */
-  output_line = 1;
-  skeleton_line = 1;
-  c = getc (fskel);
-  while (c != EOF)
-    {
-      if (c != '%')
-       {
-         if (c == '\n')
-           {
-             ++output_line;
-             ++skeleton_line;
-           }
-         putc (c, out);
-         c = getc (fskel);
-       }
-      else if ((c = getc (fskel)) == '%')
-       {
-         /* Read the muscle.  */
-         const char *muscle_key = 0;
-         const char *muscle_value = 0;
-
-         while (isalnum (c = getc (fskel)) || c == '-')
-           obstack_1grow (&muscle_obstack, c);
-         obstack_1grow (&muscle_obstack, 0);
-
-         /* Output the right value, or see if it's something special.  */
-         muscle_key = obstack_finish (&muscle_obstack);
-         muscle_value = muscle_find (muscle_key);
-         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"))
-           fprintf (out, "%d", output_line);
-         else if (!strcmp (muscle_key, "tokendef"))
-           token_definitions_output (out, &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
-           {
-             fputs ("%%", out);
-             fputs (muscle_key, out);
-           }
-       }
-      else
-       putc ('%', out);
-    }
-
-  /* End.  */
-  xfclose (fskel);
-}
-
-/*----------------------------------------.
-| Prepare the master parser to be output  |
-`----------------------------------------*/
+/*---------------------------.
+| Call the skeleton parser.  |
+`---------------------------*/
 
 static void
-output_master_parser (void)
+output_skeleton (void)
 {
-  FILE *parser = xfopen (parser_file_name, "w");
+  /* Find the right skeleton file.  */
   if (!skeleton)
     {
       if (semantic_parser)
-       skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
+       skeleton = "bison.hairy";
       else
-       skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
+       skeleton = "bison.simple";
     }
+
+  /* Parse the skeleton file and output the needed parsers.  */
   muscle_insert ("skeleton", skeleton);
-  muscle_insert ("parser-file-name", parser_file_name);
 
-  output_parser (skeleton, parser);
-  xfclose (parser);
-}
+  /* Store the definition of all the muscles. */
+  {
+    FILE *muscles_m4 = xfopen ("/tmp/muscles.m4", "w");
+    /* There are no comments, especially not `#': we do want M4 expansion
+       after `#': think of CPP macros!  */
+    fprintf (muscles_m4, "m4_changecom()\n");
+    fprintf (muscles_m4, "m4_init()\n");
 
+    fprintf (muscles_m4, "m4_define([b4_actions], \n[[");
+    actions_output (muscles_m4);
+    fprintf (muscles_m4, "]])\n\n");
 
-/* FIXME. */
+    fprintf (muscles_m4, "m4_define([b4_guards], \n[[");
+    guards_output (muscles_m4);
+    fprintf (muscles_m4, "]])\n\n");
 
-#define MUSCLE_INSERT_INT(Key, Value)                          \
-{                                                              \
-  obstack_fgrow1 (&muscle_obstack, "%d", Value);               \
-  obstack_1grow (&muscle_obstack, 0);                          \
-  muscle_insert (Key, obstack_finish (&muscle_obstack));       \
-}
+    fprintf (muscles_m4, "m4_define([b4_tokendef], \n[[");
+    token_definitions_output (muscles_m4);
+    fprintf (muscles_m4, "]])\n\n");
 
-#define MUSCLE_INSERT_STRING(Key, Value)                       \
-{                                                              \
-  obstack_sgrow (&muscle_obstack, Value);                      \
-  obstack_1grow (&muscle_obstack, 0);                          \
-  muscle_insert (Key, obstack_finish (&muscle_obstack));       \
-}
+    muscles_m4_output (muscles_m4);
+
+    fprintf (muscles_m4, "m4_wrap([m4_divert_pop(0)])\n");
+    fprintf (muscles_m4, "m4_divert_push(0)dnl\n");
+    xfclose (muscles_m4);
+  }
 
-#define MUSCLE_INSERT_PREFIX(Key, Value)                               \
-{                                                                      \
-  obstack_fgrow2 (&muscle_obstack, "%s%s", spec_name_prefix, Value);   \
-  obstack_1grow (&muscle_obstack, 0);                                  \
-  muscle_insert (Key, obstack_finish (&muscle_obstack));               \
+  /* Invoke m4 on the definition of the muscles, and the skeleton. */
+  {
+    const char *bison_pkgdatadir = getenv ("BISON_PKGDATADIR");
+    if (!bison_pkgdatadir)
+      bison_pkgdatadir = PKGDATADIR;
+    skel_in = readpipe ("m4",
+                       "-I",
+                       bison_pkgdatadir,
+                       "m4sugar/m4sugar.m4",
+                       "/tmp/muscles.m4",
+                       skeleton,
+                       NULL);
+    if (!skel_in)
+      error (EXIT_FAILURE, errno, "cannot run m4");
+    skel_lex ();
+  }
 }
 
 static void
@@ -1090,18 +1022,25 @@ 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 ("error-verbose", error_verbose);
-  MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
+  MUSCLE_INSERT_INT ("error_verbose", error_verbose);
+  MUSCLE_INSERT_STRING ("prefix", spec_name_prefix ? spec_name_prefix : "yy");
+
+  /* FIXME: This is wrong: the muscles should decide whether they hold
+     a copy or not, but the situation is too obscure currently.  */
+  MUSCLE_INSERT_STRING ("output_infix", output_infix ? output_infix : "");
+  MUSCLE_INSERT_STRING ("output_prefix", short_base_name);
+  MUSCLE_INSERT_STRING ("output_parser_name", parser_file_name);
+  MUSCLE_INSERT_STRING ("output_header_name", spec_defines_file);
 
   MUSCLE_INSERT_INT ("nnts", nvars);
   MUSCLE_INSERT_INT ("nrules", nrules);
   MUSCLE_INSERT_INT ("nstates", nstates);
   MUSCLE_INSERT_INT ("ntokens", ntokens);
 
-  MUSCLE_INSERT_INT ("locations-flag", locations_flag);
+  MUSCLE_INSERT_INT ("locations_flag", locations_flag);
+  MUSCLE_INSERT_INT ("defines_flag", defines_flag);
 }
 
-
 /*-------------------------.
 | Output the header file.  |
 `-------------------------*/
@@ -1109,14 +1048,13 @@ prepare (void)
 static void
 header_output (void)
 {
-  size_t dummy_line;
   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);
 
-  token_definitions_output (out, &dummy_line);
+  token_definitions_output (out);
   fprintf (out, "\
 #ifndef YYSTYPE\n\
 typedef %s
@@ -1127,7 +1065,27 @@ yystype;\n\
 
   if (!pure_parser)
     fprintf (out, "\nextern YYSTYPE %slval;\n",
-            spec_name_prefix);
+            spec_name_prefix ? spec_name_prefix : "yy");
+
+  if (locations_flag)
+    {
+      fputs ("\n\n", out);
+      fprintf (out, "\
+#ifndef YYLTYPE\n\
+typedef struct yyltype\n\
+{\n\
+  int first_line;\n\
+  int first_column;\n\
+  int last_line;\n\
+  int last_column;\n\
+} yyltype;\n\
+# define YYLTYPE yyltype\n\
+#endif\n");
+      if (!pure_parser)
+       fprintf (out, "\nextern YYLTYPE %slloc;\n",
+                spec_name_prefix ? spec_name_prefix : "yy");
+    }
+
   if (semantic_parser)
     {
       int i;
@@ -1167,10 +1125,12 @@ output (void)
   obstack_1grow (&attrs_obstack, 0);
   muscle_insert ("prologue", obstack_finish (&attrs_obstack));
 
-  /* Output the parser. */
-  output_master_parser ();
+  /* Process the selected skeleton file.  */
+  output_skeleton ();
+
   /* Output the header if needed. */
-  if (defines_flag)
+
+  if (0)
     header_output ();
 
   free (rules + 1);