mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-19 17:23:02 +00:00
grammar: record the kind of %define variable values
Provide a means to tell the difference between "keyword" values (e.g.,
%define api.pull both), "string" values (e.g., %define file.name
"foo"), and "code" values (e.g., %define api.namespace {calc}).
Suggested by Joel E. Denny.
http://lists.gnu.org/archive/html/bison-patches/2013-03/msg00016.html
* src/muscle-tab.h, src/muscle-tab.c (muscle_kind, muscle_kind_new)
(muscle_kind_string): New.
(muscle_percent_define_insert): Take the kind as new argument.
Insert it in the muscle table.
Adjust callers.
* src/getargs.c: Adjust callers.
* src/parse-gram.y: Ditto.
(content.opt): Remove, replaced by...
(value): this new non-terminal, whose semantics value is stored
in the new "value" union member.
Provide a printer.
Support values in braces in additions to keyword and string values.
fuse me
This commit is contained in:
@@ -582,6 +582,7 @@ getargs (int argc, char *argv[])
|
|||||||
if (value)
|
if (value)
|
||||||
*value++ = 0;
|
*value++ = 0;
|
||||||
muscle_percent_define_insert (name, command_line_location (),
|
muscle_percent_define_insert (name, command_line_location (),
|
||||||
|
muscle_string,
|
||||||
value ? value : "",
|
value ? value : "",
|
||||||
c == 'D' ? MUSCLE_PERCENT_DEFINE_D
|
c == 'D' ? MUSCLE_PERCENT_DEFINE_D
|
||||||
: MUSCLE_PERCENT_DEFINE_F);
|
: MUSCLE_PERCENT_DEFINE_F);
|
||||||
@@ -666,7 +667,8 @@ getargs (int argc, char *argv[])
|
|||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
muscle_percent_define_insert ("parse.trace",
|
muscle_percent_define_insert ("parse.trace",
|
||||||
command_line_location (), "",
|
command_line_location (),
|
||||||
|
muscle_keyword, "",
|
||||||
MUSCLE_PERCENT_DEFINE_D);
|
MUSCLE_PERCENT_DEFINE_D);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,31 @@
|
|||||||
#include "muscle-tab.h"
|
#include "muscle-tab.h"
|
||||||
#include "quote.h"
|
#include "quote.h"
|
||||||
|
|
||||||
|
muscle_kind
|
||||||
|
muscle_kind_new (char const *k)
|
||||||
|
{
|
||||||
|
if (STREQ (k, "code"))
|
||||||
|
return muscle_code;
|
||||||
|
else if (STREQ (k, "keyword"))
|
||||||
|
return muscle_keyword;
|
||||||
|
else if (STREQ (k, "string"))
|
||||||
|
return muscle_string;
|
||||||
|
aver (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char const *
|
||||||
|
muscle_kind_string (muscle_kind k)
|
||||||
|
{
|
||||||
|
switch (k)
|
||||||
|
{
|
||||||
|
case muscle_code: return "code";
|
||||||
|
case muscle_keyword: return "keyword";
|
||||||
|
case muscle_string: return "string";
|
||||||
|
}
|
||||||
|
aver (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* A key-value pair, along with storage that can be reclaimed when
|
/* A key-value pair, along with storage that can be reclaimed when
|
||||||
this pair is no longer needed. */
|
this pair is no longer needed. */
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -35,6 +60,7 @@ typedef struct
|
|||||||
char const *key;
|
char const *key;
|
||||||
char const *value;
|
char const *value;
|
||||||
char *storage;
|
char *storage;
|
||||||
|
muscle_kind kind;
|
||||||
} muscle_entry;
|
} muscle_entry;
|
||||||
|
|
||||||
/* An obstack used to create some entries. */
|
/* An obstack used to create some entries. */
|
||||||
@@ -446,6 +472,7 @@ muscle_percent_variable_update (char const *variable, location variable_loc,
|
|||||||
|
|
||||||
void
|
void
|
||||||
muscle_percent_define_insert (char const *var, location variable_loc,
|
muscle_percent_define_insert (char const *var, location variable_loc,
|
||||||
|
muscle_kind kind,
|
||||||
char const *value,
|
char const *value,
|
||||||
muscle_percent_define_how how)
|
muscle_percent_define_how how)
|
||||||
{
|
{
|
||||||
@@ -456,6 +483,8 @@ muscle_percent_define_insert (char const *var, location variable_loc,
|
|||||||
char const *syncline_name =
|
char const *syncline_name =
|
||||||
UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
|
UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
|
||||||
char const *how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")");
|
char const *how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")");
|
||||||
|
char const *kind_name =
|
||||||
|
UNIQSTR_CONCAT ("percent_define_kind(", variable, ")");
|
||||||
|
|
||||||
/* Command-line options are processed before the grammar file. */
|
/* Command-line options are processed before the grammar file. */
|
||||||
if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
|
if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
|
||||||
@@ -481,6 +510,7 @@ muscle_percent_define_insert (char const *var, location variable_loc,
|
|||||||
muscle_user_name_list_grow ("percent_define_user_variables", variable,
|
muscle_user_name_list_grow ("percent_define_user_variables", variable,
|
||||||
variable_loc);
|
variable_loc);
|
||||||
MUSCLE_INSERT_INT (how_name, how);
|
MUSCLE_INSERT_INT (how_name, how);
|
||||||
|
MUSCLE_INSERT_STRING (kind_name, muscle_kind_string (kind));
|
||||||
end:
|
end:
|
||||||
free (variable);
|
free (variable);
|
||||||
}
|
}
|
||||||
@@ -497,10 +527,10 @@ muscle_percent_define_ensure (char const *variable, location loc,
|
|||||||
/* Don't complain is VARIABLE is already defined, but be sure to set
|
/* Don't complain is VARIABLE is already defined, but be sure to set
|
||||||
its value to VAL. */
|
its value to VAL. */
|
||||||
if (!muscle_find_const (name))
|
if (!muscle_find_const (name))
|
||||||
muscle_percent_define_insert (variable, loc, val,
|
muscle_percent_define_insert (variable, loc, muscle_keyword, val,
|
||||||
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
||||||
if (muscle_percent_define_flag_if (variable) != value)
|
if (muscle_percent_define_flag_if (variable) != value)
|
||||||
muscle_percent_define_insert (variable, loc, val,
|
muscle_percent_define_insert (variable, loc, muscle_keyword, val,
|
||||||
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,12 +24,29 @@
|
|||||||
|
|
||||||
# include "location.h"
|
# include "location.h"
|
||||||
|
|
||||||
|
/* The kind of value associated to this muscle, depending on the
|
||||||
|
syntax of the value: keyword (no delimiter, e.g., true), string
|
||||||
|
(double quotes, e.g., "foo.h"), or code (braces, e.g., {int}). */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
muscle_code,
|
||||||
|
muscle_keyword,
|
||||||
|
muscle_string
|
||||||
|
} muscle_kind;
|
||||||
|
|
||||||
|
/* Conversion from string. */
|
||||||
|
muscle_kind muscle_kind_new (char const *k);
|
||||||
|
|
||||||
|
/* Conversion to string. */
|
||||||
|
char const *muscle_kind_string (muscle_kind k);
|
||||||
|
|
||||||
|
|
||||||
/* Create the MUSCLE_TABLE, and initialize it with default values.
|
/* Create the MUSCLE_TABLE, and initialize it with default values.
|
||||||
Also set up the MUSCLE_OBSTACK. */
|
Also set up the MUSCLE_OBSTACK. */
|
||||||
void muscle_init (void);
|
void muscle_init (void);
|
||||||
|
|
||||||
/* Insert (KEY, VALUE). If KEY already existed, overwrite the
|
/* Insert (KEY, VALUE). If KEY already existed, overwrite the
|
||||||
previous value. */
|
previous value. Otherwise create as a muscle_string type. */
|
||||||
void muscle_insert (char const *key, char const *value);
|
void muscle_insert (char const *key, char const *value);
|
||||||
|
|
||||||
/* Find the value of muscle KEY. Unlike MUSCLE_FIND, this is always
|
/* Find the value of muscle KEY. Unlike MUSCLE_FIND, this is always
|
||||||
@@ -124,6 +141,7 @@ typedef enum {
|
|||||||
this as a user occurrence of VARIABLE by invoking
|
this as a user occurrence of VARIABLE by invoking
|
||||||
muscle_user_name_list_grow. */
|
muscle_user_name_list_grow. */
|
||||||
void muscle_percent_define_insert (char const *variable, location variable_loc,
|
void muscle_percent_define_insert (char const *variable, location variable_loc,
|
||||||
|
muscle_kind kind,
|
||||||
char const *value,
|
char const *value,
|
||||||
muscle_percent_define_how how);
|
muscle_percent_define_how how);
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "getargs.h"
|
#include "getargs.h"
|
||||||
#include "gram.h"
|
#include "gram.h"
|
||||||
#include "muscle-tab.h"
|
|
||||||
#include "named-ref.h"
|
#include "named-ref.h"
|
||||||
#include "quotearg.h"
|
#include "quotearg.h"
|
||||||
#include "reader.h"
|
#include "reader.h"
|
||||||
@@ -179,12 +178,12 @@ static char const *char_name (char);
|
|||||||
char *code;
|
char *code;
|
||||||
char const *chars;
|
char const *chars;
|
||||||
};
|
};
|
||||||
%type <chars> STRING "%{...%}" EPILOGUE braceless content.opt
|
%type <chars> STRING "%{...%}" EPILOGUE braceless
|
||||||
%type <code> "{...}" "%?{...}"
|
%type <code> "{...}" "%?{...}"
|
||||||
%printer { fputs (quotearg_style (c_quoting_style, $$), yyo); }
|
%printer { fputs (quotearg_style (c_quoting_style, $$), yyo); }
|
||||||
STRING
|
STRING
|
||||||
%printer { fprintf (yyo, "{\n%s\n}", $$); }
|
%printer { fprintf (yyo, "{\n%s\n}", $$); }
|
||||||
braceless content.opt "{...}" "%{...%}" EPILOGUE
|
braceless "{...}" "%{...%}" EPILOGUE
|
||||||
|
|
||||||
%union {uniqstr uniqstr;}
|
%union {uniqstr uniqstr;}
|
||||||
%type <uniqstr> BRACKETED_ID ID ID_COLON PERCENT_FLAG TAG tag variable
|
%type <uniqstr> BRACKETED_ID ID ID_COLON PERCENT_FLAG TAG tag variable
|
||||||
@@ -288,9 +287,9 @@ prologue_declaration:
|
|||||||
{
|
{
|
||||||
muscle_percent_define_ensure ($1, @1, true);
|
muscle_percent_define_ensure ($1, @1, true);
|
||||||
}
|
}
|
||||||
| "%define" variable content.opt
|
| "%define" variable value
|
||||||
{
|
{
|
||||||
muscle_percent_define_insert ($2, @2, $3,
|
muscle_percent_define_insert ($2, @2, $3.kind, $3.chars,
|
||||||
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
||||||
}
|
}
|
||||||
| "%defines" { defines_flag = true; }
|
| "%defines" { defines_flag = true; }
|
||||||
@@ -301,7 +300,8 @@ prologue_declaration:
|
|||||||
}
|
}
|
||||||
| "%error-verbose"
|
| "%error-verbose"
|
||||||
{
|
{
|
||||||
muscle_percent_define_insert ("parse.error", @1, "verbose",
|
muscle_percent_define_insert ("parse.error", @1, muscle_keyword,
|
||||||
|
"verbose",
|
||||||
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
||||||
}
|
}
|
||||||
| "%expect" INT { expected_sr_conflicts = $2; }
|
| "%expect" INT { expected_sr_conflicts = $2; }
|
||||||
@@ -634,9 +634,9 @@ named_ref.opt:
|
|||||||
| BRACKETED_ID { $$ = named_ref_new($1, @1); }
|
| BRACKETED_ID { $$ = named_ref_new($1, @1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/*---------------------------.
|
/*---------------------.
|
||||||
| variable and content.opt. |
|
| variable and value. |
|
||||||
`---------------------------*/
|
`---------------------*/
|
||||||
|
|
||||||
/* The STRING form of variable is deprecated and is not M4-friendly.
|
/* The STRING form of variable is deprecated and is not M4-friendly.
|
||||||
For example, M4 fails for '%define "[" "value"'. */
|
For example, M4 fails for '%define "[" "value"'. */
|
||||||
@@ -646,10 +646,31 @@ variable:
|
|||||||
;
|
;
|
||||||
|
|
||||||
/* Some content or empty by default. */
|
/* Some content or empty by default. */
|
||||||
content.opt:
|
%code requires {#include "muscle-tab.h"};
|
||||||
%empty { $$ = ""; }
|
%union
|
||||||
| ID { $$ = $1; }
|
{
|
||||||
| STRING { $$ = $1; }
|
struct
|
||||||
|
{
|
||||||
|
char const *chars;
|
||||||
|
muscle_kind kind;
|
||||||
|
} value;
|
||||||
|
};
|
||||||
|
%type <value> value;
|
||||||
|
%printer
|
||||||
|
{
|
||||||
|
switch ($$.kind)
|
||||||
|
{
|
||||||
|
case muscle_code: fprintf (yyo, "{%s}", $$.chars); break;
|
||||||
|
case muscle_keyword: fprintf (yyo, "%s", $$.chars); break;
|
||||||
|
case muscle_string: fprintf (yyo, "\"%s\"", $$.chars); break;
|
||||||
|
}
|
||||||
|
} <value>;
|
||||||
|
|
||||||
|
value:
|
||||||
|
%empty { $$.kind = muscle_keyword; $$.chars = ""; }
|
||||||
|
| ID { $$.kind = muscle_keyword; $$.chars = $1; }
|
||||||
|
| STRING { $$.kind = muscle_string; $$.chars = $1; }
|
||||||
|
| braceless { $$.kind = muscle_code; $$.chars = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user