]> git.saurik.com Git - bison.git/blobdiff - src/output.c
Really add m4sugar to the repo.
[bison.git] / src / output.c
index 80fc643b7aeabfa79a06b716c3b76eed2148362b..702f0cb18bf8f95608f8e0e79013272fb1f8be0f 100644 (file)
@@ -1,5 +1,5 @@
 /* Output the generated parsing program for bison,
 /* 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.
    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 "system.h"
 #include "quotearg.h"
+#include "error.h"
 #include "getargs.h"
 #include "files.h"
 #include "gram.h"
 #include "getargs.h"
 #include "files.h"
 #include "gram.h"
 #include "conflicts.h"
 #include "muscle_tab.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;
 
 static int nvectors;
 static int nentries;
@@ -504,7 +511,7 @@ token_actions (void)
 `-----------------------------*/
 
 void
 `-----------------------------*/
 
 void
-actions_output (FILE *out, size_t *line)
+actions_output (FILE *out)
 {
   int rule;
   for (rule = 1; rule < nrules + 1; ++rule)
 {
   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 ? ";" : "");
        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);
       }
 }
 
       }
 }
 
@@ -540,11 +539,11 @@ actions_output (FILE *out, size_t *line)
 `----------------------------*/
 
 void
 `----------------------------*/
 
 void
-guards_output (FILE *out, size_t *line)
+guards_output (FILE *out)
 {
   int rule;
   for (rule = 1; rule < nrules + 1; ++rule)
 {
   int rule;
   for (rule = 1; rule < nrules + 1; ++rule)
-    if (rules[rule].action)
+    if (rules[rule].guard)
       {
        fprintf (out, "  case %d:\n", rule);
 
       {
        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);
                                   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);
       }
 }
 
       }
 }
 
@@ -572,7 +563,7 @@ guards_output (FILE *out, size_t *line)
 `---------------------------------------*/
 
 void
 `---------------------------------------*/
 
 void
-token_definitions_output (FILE *out, size_t *line)
+token_definitions_output (FILE *out)
 {
   int i;
   for (i = 0; i < ntokens; ++i)
 {
   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);
 
       fprintf (out, "# define %s\t%d\n",
               symbol->tag, number);
-      ++*line;
       if (semantic_parser)
       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,124 +948,68 @@ output_actions (void)
 }
 
 \f
 }
 
 \f
-/*------------------------------------------------------------.
-| Copy the parser code from SKEL_FILENAME into OOUT obstack.  |
-| and do the muscle substitution.                             |
-`------------------------------------------------------------*/
+/*---------------------------.
+| Call the skeleton parser.  |
+`---------------------------*/
 
 static void
 
 static void
-output_parser (const char *skel_filename, FILE *out)
+output_skeleton (void)
 {
 {
-  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)
+  /* Find the right skeleton file.  */
+  if (!skeleton)
     {
     {
-      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);
-           }
-       }
+      if (semantic_parser)
+       skeleton = "bison.hairy";
       else
       else
-       putc ('%', out);
+       skeleton = "bison.simple";
     }
 
     }
 
-  /* End.  */
-  xfclose (fskel);
-}
-
-/*----------------------------------------.
-| Prepare the master parser to be output  |
-`----------------------------------------*/
+  /* Parse the skeleton file and output the needed parsers.  */
+  muscle_insert ("skeleton", skeleton);
 
 
-static void
-output_master_parser (void)
-{
-  FILE *parser = xfopen (parser_file_name, "w");
+  /* 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");
 
 
-  /* FIXME: Remove the two following lines.  */
-  printf ("Test: %s\n", infile);
-  printf ("Test: %s\n", parser_file_name);
+    fprintf (muscles_m4, "m4_define([b4_actions], \n[[");
+    actions_output (muscles_m4);
+    fprintf (muscles_m4, "]])\n\n");
 
 
-  if (!skeleton)
-    {
-      if (semantic_parser)
-       skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
-      else
-       skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
-    }
-  muscle_insert ("skeleton", skeleton);
-  muscle_insert ("parser-file-name", parser_file_name);
+    fprintf (muscles_m4, "m4_define([b4_guards], \n[[");
+    guards_output (muscles_m4);
+    fprintf (muscles_m4, "]])\n\n");
 
 
-  output_parser (skeleton, parser);
-  xfclose (parser);
-}
+    fprintf (muscles_m4, "m4_define([b4_tokendef], \n[[");
+    token_definitions_output (muscles_m4);
+    fprintf (muscles_m4, "]])\n\n");
 
 
-/* Call the skeleton parser.  */
+    muscles_m4_output (muscles_m4);
 
 
-static 
-void
-output_skeleton ()
-{
-  /* Find the right skeleton file.  */
-  if (!skeleton)
-    {
-      if (semantic_parser)
-       skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
-      else
-       skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
-    }
+    fprintf (muscles_m4, "m4_wrap([m4_divert_pop(0)])\n");
+    fprintf (muscles_m4, "m4_divert_push(0)dnl\n");
+    xfclose (muscles_m4);
+  }
 
 
-  /* Parse the skeleton file and output the needed parsers.  */
-  muscle_insert ("skeleton", skeleton);
-  process_skeleton (infile, skeleton);
+  /* 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
 }
 
 static void
@@ -1091,15 +1022,23 @@ 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 ("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_INT ("error_verbose", error_verbose);
   MUSCLE_INSERT_STRING ("prefix", spec_name_prefix ? spec_name_prefix : "yy");
 
   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 ("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);
 }
 
 /*-------------------------.
 }
 
 /*-------------------------.
@@ -1109,14 +1048,13 @@ prepare (void)
 static void
 header_output (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);
 
   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
   fprintf (out, "\
 #ifndef YYSTYPE\n\
 typedef %s
@@ -1190,12 +1128,9 @@ output (void)
   /* Process the selected skeleton file.  */
   output_skeleton ();
 
   /* Process the selected skeleton file.  */
   output_skeleton ();
 
-  /* Output the parser. */
-#if 0
-  output_master_parser ();
-#endif
   /* Output the header if needed. */
   /* Output the header if needed. */
-  if (defines_flag)
+
+  if (0)
     header_output ();
 
   free (rules + 1);
     header_output ();
 
   free (rules + 1);