%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 { }
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);
}
;
-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. */ { }
}
;
%%
+/*------------------------------------------------------------------.
+| 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)