X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/24fad99e2bb2bdb0d5bd62571a0be8d60b97e2f8..be2a1a68efe93f7046f77b81346e4c740c14fb40:/src/parse-skel.y diff --git a/src/parse-skel.y b/src/parse-skel.y index 8cf7fcd5..ccb5e43f 100644 --- a/src/parse-skel.y +++ b/src/parse-skel.y @@ -22,65 +22,84 @@ %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 +%token MUSCLE /* A string dedicated to Bison (%%"foo"). */ %token STRING /* Raw data, to output directly. */ -%token RAW +%token RAW /* Spaces. */ -%token BLANKS +%token BLANKS /* Raw data, but char by char. */ %token CHARACTER %token LINE %token SLINE -%token YACC %token SECTION %token GUARDS %token TOKENS %token ACTIONS -%type section.yacc +%type 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)