]> git.saurik.com Git - bison.git/blobdiff - src/parse-skel.y
Give a try to M4 as a back end.
[bison.git] / src / parse-skel.y
index 8cf7fcd5d3bd92629b68ffd455b8599e768e4e2a..ccb5e43fd123349abf4b661c4e73332b405d40bd 100644 (file)
 %debug
 %defines
 %verbose
-%error-verbose
+%locations
+%name-prefix="skel_"
+%pure-parser
 
 %{
 #include "system.h"
 #include "obstack.h"
+#include "quotearg.h"
 #include "files.h"
+#include "getargs.h"
 #include "output.h"
 #include "skeleton.h"
 #include "muscle_tab.h"
 
-extern FILE* yyin;
-extern int   yylineno;
+#define YYERROR_VERBOSE 1
+
+/* Pass the control structure to YYPARSE but not YYLEX (yet?). */
+#define YYPARSE_PARAM skel_control
+/* YYPARSE receives SKEL_CONTROL as a void *.  Provide a correctly
+   typed access to it.  */
+#define yycontrol ((skel_control_t *) skel_control)
 
-char* prefix = NULL;
 FILE* parser = NULL;
 
 size_t output_line;
 size_t skeleton_line;
 
-static int merror PARAMS ((const char* error));
-static int yyerror PARAMS ((const char* error));
+static void merror PARAMS ((const char* error));
+
+/* Request detailed parse error messages, and pass them to
+   YLEVAL_ERROR. */
+#undef  yyerror
+#define yyerror(Msg) \
+        skel_error (yycontrol, &yylloc, Msg)
 
+/* When debugging our pure parser, we want to see values and locations
+   of the tokens.  */
+#define YYPRINT(File, Type, Value) \
+        yyprint (File, &yylloc, Type, &Value)
+static void yyprint (FILE *file, const yyltype *loc,
+                     int type, const yystype *value);
 %}
 
 %union
 {
-  char *muscle;
   char *string;
-  char *literal;
   char character;
-  int yacc;
+  int  boolean;
 }
 
 /* Name of a muscle. */
-%token <muscle> MUSCLE
+%token <string> MUSCLE
 /* A string dedicated to Bison (%%"foo").  */
 %token <string> STRING
 /* Raw data, to output directly. */
-%token <literal> RAW
+%token <string> RAW
 /* Spaces. */
-%token <literal> BLANKS
+%token <string> BLANKS
 /* Raw data, but char by char. */
 %token <character> CHARACTER
 
 %token LINE
 %token SLINE
 
-%token YACC
 %token SECTION
 
 %token GUARDS
 %token TOKENS
 %token ACTIONS
 
-%type <yacc> section.yacc
+%type <string> string.1 string
 
-%start skeleton
+%start input
 
 %%
+input:
+     { LOCATION_RESET (yylloc) } skeleton
+  ;
 
 skeleton : /* Empty.  */    { }
          | section skeleton { }
@@ -89,43 +108,14 @@ skeleton : /* Empty.  */    { }
 section : section.header section.body { }
 ;
 
-section.header : SECTION BLANKS MUSCLE BLANKS STRING BLANKS section.yacc '\n'
+section.header : SECTION BLANKS string '\n'
 {
-  char *name = 0;
-  char *limit = 0;
-  char *suffix = $5;
+  char *name = $3;
 
   /* Close the previous parser.  */
   if (parser)
     parser = (xfclose (parser), NULL);
 
-  /* If the following section should be named with the yacc-style, and it's
-     suffix is of the form 'something.h' or 'something.c', then add '.tab' in
-     the middle of the suffix.  */
-  if (tab_extension && $7 && (strsuffix (suffix, ".h") ||
-                             strsuffix (suffix, ".c")))
-    {
-      size_t prefix_len = strlen (prefix);
-      size_t suffix_len = strlen (suffix);
-
-      /* Allocate enough space to insert '.tab'.  */
-      name = XMALLOC (char, prefix_len + suffix_len + 5);
-      limit = strrchr (suffix, '.');
-      if (!limit)
-       limit = suffix;
-
-      /* Prefix is 'X', suffix is 'Y.Z'.  Name will be 'XY.tab.Z'.  */
-      {
-       char* cp = 0;
-       cp = stpcpy (name, prefix);
-       cp = stpncpy (cp, suffix, limit - suffix);
-       cp = stpcpy (cp, ".tab");
-       cp = stpcpy (cp, limit);
-      }
-    }
-  else
-    name = stringappend (prefix, suffix);
-
   /* Prepare the next parser to be output.  */
   parser = xfopen (name, "w");
   MUSCLE_INSERT_STRING ("parser-file-name", name);
@@ -135,9 +125,20 @@ section.header : SECTION BLANKS MUSCLE BLANKS STRING BLANKS section.yacc '\n'
 }
 ;
 
-section.yacc : /* Empty.  */ { $$ = 0; }
-             | YACC          { $$ = 1; }
-;
+/* Either a literal string, or a muscle value.  */
+string.1:
+    STRING { $$ = $1; }
+  | MUSCLE { $$ = xstrdup (muscle_find ($1)); }
+  ;
+
+/* Either a literal string, or a muscle value, or the concatenation of
+   them.  */
+string:
+    string.1
+    { $$ = $1; }
+  | string BLANKS string.1
+    { $$ = stringappend ($1, $3); free ($1); free ($3); }
+  ;
 
 section.body
 : /* Empty.  */ { }
@@ -165,36 +166,64 @@ section.body
 }
 ;
 %%
+/*------------------------------------------------------------------.
+| When debugging the parser, display tokens' locations and values.  |
+`------------------------------------------------------------------*/
 
-static int
+static void
+yyprint (FILE *file,
+         const yyltype *loc, int type, const yystype *value)
+{
+  fputs (" (", file);
+  LOCATION_PRINT (file, *loc);
+  fputs (")", file);
+  switch (type)
+    {
+    case MUSCLE:
+    case STRING:
+    case RAW:
+    case BLANKS:
+      fprintf (file, " = %s", quotearg_style (c_quoting_style,
+                                             value->string));
+      break;
+
+    case CHARACTER:
+      fprintf (file, " = '%c'", value->character);
+      break;
+    }
+}
+
+
+static void
 merror (const char* error)
 {
   printf ("line %d: %%{%s} undeclared.\n", skeleton_line, error);
-  return 0;
 }
 
-static int
-yyerror (const char* error)
+void
+skel_error (skel_control_t *control,
+           const yyltype *loc, const char *msg)
 {
-  fprintf (stderr, "%s\n", error);
-  return 0;
+  /* Neutralize GCC warnings for unused parameters. */
+  skel_control_t *c = control;
+  c++;
+  LOCATION_PRINT (stderr, *loc);
+  fprintf (stderr, "%s\n", msg);
 }
 
 void
 process_skeleton (const char* skel)
 {
-  /* Compute prefix.  Actually, it seems that the processing I need here is
-     done in compute_base_names, and the result stored in short_base_name.  */
-  prefix = short_base_name;
-
   /* Prepare a few things.  */
   output_line = 1;
   skeleton_line = 1;
 
   /* Output.  */
-  yyin = fopen (skel, "r");
-  yydebug = 0;
-  yyparse ();
+  skel_in = fopen (skel, "r");
+  /* FIXME: This is not acceptable for a release. */
+  skel__flex_debug = getenv ("BISON_TRACE_SCAN") ? 1 : 0;
+  skel_debug = getenv ("BISON_TRACE_PARSE") ? 1 : 0;
+  skel_parse (NULL);
 
   /* Close the last parser.  */
   if (parser)