From 9611cfa20bf95cf06b79c598ae5e69979ea1ff8e Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Fri, 2 Mar 2007 06:26:28 +0000 Subject: [PATCH] Miscellaneous %define and %code cleanup. * data/bison.m4 (b4_percent_define_flag_if): Correct comments on how values are interpreted. * doc/bison.texinfo (Decl Summary): Clean up and extend %define documentation a little more. * src/muscle_tab.c (MUSCLE_USER_NAME_CONVERT, muscle_percent_define_insert, muscle_percent_code_grow): New functions/macros. * src/muscle_tab.h (muscle_percent_define_insert, muscle_percent_code_grow): Prototype. * src/parse-gram.y (prologue_declaration): Use muscle_percent_define_insert and muscle_percent_code_grow when parsing %define and %code directives. Make it easy to share %define boolean variables between the front-end and back-end. Though not used yet, this will be useful in the future. * data/bison.m4 (b4_check_user_names): Rewrite comments to talk about Bison uses of names rather than just skeleton uses of names. (b4_percent_define_get, b4_percent_define_ifdef): Rename b4_percent_define_skeleton_variables(VARIABLE) to b4_percent_define_bison_variables(VARIABLE). (b4_percent_code_get, b4_percent_code_ifdef): Rename b4_percent_code_skeleton_qualifiers(QUALIFIER) to b4_percent_code_bison_qualifiers(QUALIFIER). (b4_check_user_names_wrap): Update for renames. * src/muscle_tab.c, src/muscle_tab.h (muscle_percent_define_flag_if, muscle_percent_define_default): New functions mimicking b4_percent_define_flag_if and b4_percent_define_default. For %define variables, report locations for invalid values and redefinitions. * data/bison.m4 (b4_percent_define_flag_if): Read b4_percent_define_loc(VARIABLE) to report the location of an invalid value for VARIABLE. (b4_percent_define_default): Save a special location in b4_percent_define_loc(VARIABLE) in case the default value for VARIABLE must later be reported as invalid. * src/muscle_tab.c (muscle_location_grow, muscle_location_decode): New functions. (muscle_percent_define_insert): Record the location of VARIABLE in muscle percent_define_loc(VARIABLE), and use it to report the previous location for a redefinition. (muscle_percent_define_flag_if): Update like b4_percent_define_flag_if. (muscle_percent_define_default): Update like b4_percent_define_default. (muscle_grow_user_name_list): Rename to... (muscle_user_name_list_grow): ... this for consistency and use muscle_location_grow. * src/muscle_tab.h (muscle_location_grow): Prototype. * tests/input.at (%define errors): Update expected output. * tests/skeletons.at (%define boolean variables: invalid skeleton defaults): New test case. --- ChangeLog | 54 +++++++++++ data/bison.m4 | 105 ++++++++++++--------- doc/bison.texinfo | 34 +++++-- lib/.cvsignore | 2 +- src/muscle_tab.c | 230 +++++++++++++++++++++++++++++++++++++++------ src/muscle_tab.h | 37 +++++++- src/parse-gram.c | 208 +++++++++++++++++++--------------------- src/parse-gram.y | 24 +---- tests/input.at | 4 +- tests/skeletons.at | 36 ++++++- 10 files changed, 514 insertions(+), 220 deletions(-) diff --git a/ChangeLog b/ChangeLog index 109930a8..b4f79664 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,57 @@ +2007-03-02 Joel E. Denny + + Miscellaneous %define and %code cleanup. + * data/bison.m4 (b4_percent_define_flag_if): Correct comments on how + values are interpreted. + * doc/bison.texinfo (Decl Summary): Clean up and extend %define + documentation a little more. + * src/muscle_tab.c (MUSCLE_USER_NAME_CONVERT, + muscle_percent_define_insert, muscle_percent_code_grow): New + functions/macros. + * src/muscle_tab.h (muscle_percent_define_insert, + muscle_percent_code_grow): Prototype. + * src/parse-gram.y (prologue_declaration): Use + muscle_percent_define_insert and muscle_percent_code_grow when parsing + %define and %code directives. + + Make it easy to share %define boolean variables between the front-end + and back-end. Though not used yet, this will be useful in the future. + * data/bison.m4 (b4_check_user_names): Rewrite comments to talk about + Bison uses of names rather than just skeleton uses of names. + (b4_percent_define_get, b4_percent_define_ifdef): Rename + b4_percent_define_skeleton_variables(VARIABLE) to + b4_percent_define_bison_variables(VARIABLE). + (b4_percent_code_get, b4_percent_code_ifdef): Rename + b4_percent_code_skeleton_qualifiers(QUALIFIER) to + b4_percent_code_bison_qualifiers(QUALIFIER). + (b4_check_user_names_wrap): Update for renames. + * src/muscle_tab.c, src/muscle_tab.h (muscle_percent_define_flag_if, + muscle_percent_define_default): New functions mimicking + b4_percent_define_flag_if and b4_percent_define_default. + + For %define variables, report locations for invalid values and + redefinitions. + * data/bison.m4 (b4_percent_define_flag_if): Read + b4_percent_define_loc(VARIABLE) to report the location of an invalid + value for VARIABLE. + (b4_percent_define_default): Save a special location in + b4_percent_define_loc(VARIABLE) in case the default value for VARIABLE + must later be reported as invalid. + * src/muscle_tab.c (muscle_location_grow, muscle_location_decode): New + functions. + (muscle_percent_define_insert): Record the location of VARIABLE in + muscle percent_define_loc(VARIABLE), and use it to report the previous + location for a redefinition. + (muscle_percent_define_flag_if): Update like b4_percent_define_flag_if. + (muscle_percent_define_default): Update like b4_percent_define_default. + (muscle_grow_user_name_list): Rename to... + (muscle_user_name_list_grow): ... this for consistency and use + muscle_location_grow. + * src/muscle_tab.h (muscle_location_grow): Prototype. + * tests/input.at (%define errors): Update expected output. + * tests/skeletons.at (%define boolean variables: invalid skeleton + defaults): New test case. + 2007-02-28 Joel E. Denny * src/print.c (lookahead_set, state_default_rule): Remove. diff --git a/data/bison.m4 b/data/bison.m4 index f5a1a7c9..0aa1efdc 100644 --- a/data/bison.m4 +++ b/data/bison.m4 @@ -285,11 +285,11 @@ b4_define_user_code([pre_prologue]) b4_define_user_code([stype]) -# b4_check_user_names(WHAT, USER-LIST, SKELETON-NAMESPACE) +# b4_check_user_names(WHAT, USER-LIST, BISON-NAMESPACE) # -------------------------------------------------------- # Warn if any name of type WHAT is used by the user (as recorded in USER-LIST) -# but is not used by the skeleton (as recorded by macros in the namespace -# SKELETON-NAMESPACE). +# but is not used by Bison (as recorded by macros in the namespace +# BISON-NAMESPACE). # # USER-LIST must expand to a list specifying all grammar occurrences of all # names of type WHAT. Each item in the list must be a triplet specifying one @@ -304,22 +304,22 @@ b4_define_user_code([stype]) # [[[[bar]], [[parser.y:5.7]], [[parser.y:5.16]]]], # [[[[baz]], [[parser.y:8.7]], [[parser.y:8.16]]]]]]) # -# The macro SKELETON-NAMESPACE(bar) must be defined iff the name bar of type -# WHAT is used in the skeleton. Empty string names are fine, but it would be -# ugly for a Bison skeleton to actually use one. +# The macro BISON-NAMESPACE(bar) must be defined iff the name bar of type WHAT +# is used by Bison (in the front-end or in the skeleton). Empty string names +# are fine, but it would be ugly for Bison to actually use one. # -# For example, to use b4_foo_skeleton_names for SKELETON-NAMESPACE and define -# that the names bar and baz are used in the skeleton: +# For example, to use b4_foo_bison_names for BISON-NAMESPACE and define that +# the names bar and baz are used by Bison: # -# m4_define([b4_foo_skeleton_names(bar)]) -# m4_define([b4_foo_skeleton_names(baz)]) +# m4_define([b4_foo_bison_names(bar)]) +# m4_define([b4_foo_bison_names(baz)]) # # To invoke b4_check_user_names with TYPE foo, with USER-LIST -# b4_foo_user_names, with SKELETON-NAMESPACE b4_foo_skeleton_names, and with -# correct quoting: +# b4_foo_user_names, with BISON-NAMESPACE b4_foo_bison_names, and with correct +# quoting: # # b4_check_user_names([[foo]], [b4_foo_user_names], -# [[b4_foo_skeleton_names]]) +# [[b4_foo_bison_names]]) m4_define([b4_check_user_names], [m4_foreach([b4_occurrence], $2, [m4_pushdef([b4_occurrence], b4_occurrence)dnl @@ -339,60 +339,79 @@ m4_popdef([b4_end])dnl # b4_percent_define_get(VARIABLE) # ------------------------------- # If the %define variable VARIABLE is defined, emit its value. Also, record -# the skeleton's usage of VARIABLE by defining -# b4_percent_define_skeleton_variables(VARIABLE). +# Bison's usage of VARIABLE by defining +# b4_percent_define_bison_variables(VARIABLE). # # For example: # # b4_percent_define_get([[foo]]) m4_define([b4_percent_define_get], -[m4_define([b4_percent_define_skeleton_variables(]$1[)])dnl +[m4_define([b4_percent_define_bison_variables(]$1[)])dnl m4_ifdef([b4_percent_define(]$1[)], [m4_indir([b4_percent_define(]$1[)])])]) # b4_percent_define_ifdef(VARIABLE, IF-TRUE, [IF-FALSE]) # ------------------------------------------------------ # If the %define variable VARIABLE is defined, expand IF-TRUE, else expand -# IF-FALSE. Also, record the skeleton's usage of VARIABLE by defining -# b4_percent_define_skeleton_variables(VARIABLE). +# IF-FALSE. Also, record Bison's usage of VARIABLE by defining +# b4_percent_define_bison_variables(VARIABLE). +# +# For example: +# +# b4_percent_define_ifdef([[foo]], [[it's defined]], [[it's undefined]]) m4_define([b4_percent_define_ifdef], [m4_ifdef([b4_percent_define(]$1[)], - [m4_define([b4_percent_define_skeleton_variables(]$1[)])$2], + [m4_define([b4_percent_define_bison_variables(]$1[)])$2], [$3])]) # b4_percent_define_flag_if(VARIABLE, IF-TRUE, [IF-FALSE]) # -------------------------------------------------------- -# If the %define variable VARIABLE is defined to anything but "0" or "false", -# expand IF-TRUE. If it is defined to "0" or "false", expand IF-FALSE. If -# it is undefined, raise an error (this macro should be preceded by -# b4_percent_define_default). Also, record the skeleton's usage of VARIABLE by -# defining b4_percent_define_skeleton_variables(VARIABLE). +# Mimic muscle_percent_define_flag_if in ../src/muscle_tab.h exactly. That is, +# if the %define variable VARIABLE is defined to "" or "true", expand IF-TRUE. +# If it is defined to "false", expand IF-FALSE. Complain if it is undefined +# (a Bison or skeleton error since the default value should have been set +# already) or defined to any other value (possibly a user error). Also, record +# Bison's usage of VARIABLE by defining +# b4_percent_define_bison_variables(VARIABLE). +# +# For example: +# +# b4_percent_define_flag_if([[foo]], [[it's true]], [[it's false]]) m4_define([b4_percent_define_flag_if], [b4_percent_define_ifdef([$1], - [m4_case(b4_percent_define_get([$1]), - [], [$2], [true], [$2], [false], [$3], - [m4_expand_once( - [b4_complain([[invalid value for %%define variable `%s']], [$1])], - [[b4_percent_define_flag_if($1)]])])], - [b4_fatal([[invalid %%define variable `%s' passed to b4_percent_define_flag_if]], [$1])])]) + [m4_case(b4_percent_define_get([$1]), + [], [$2], [true], [$2], [false], [$3], + [m4_expand_once([dnl + m4_pushdef([b4_loc], m4_indir([b4_percent_define_loc(]$1[)]))dnl + b4_complain_at(b4_loc, + [[invalid value for %%define boolean variable `%s']], + [$1])dnl + m4_popdef([b4_loc])], + [[b4_percent_define_flag_if($1)]])])], + [b4_fatal([[undefined %%define variable `%s' passed to b4_percent_define_flag_if]], [$1])])]) # b4_percent_define_default(VARIABLE, DEFAULT) # -------------------------------------------- -# If the %define variable VARIABLE is undefined, set its value to DEFAULT. +# Mimic muscle_percent_define_default in ../src/muscle_tab.h exactly. That is, +# if the %define variable VARIABLE is undefined, set its value to DEFAULT. +# Don't record this as a Bison usage of VARIABLE as there's no reason to +# suspect that the value has yet influenced the output. # # For example: # # b4_percent_define_default([[foo]], [[default value]]) m4_define([b4_percent_define_default], [m4_ifndef([b4_percent_define(]$1[)], - [m4_define([b4_percent_define(]$1[)], [$2])])]) + [m4_define([b4_percent_define(]$1[)], [$2])dnl + m4_define([b4_percent_define_loc(]$1[)], + [[[[[Bison:b4_percent_define_default]:0.0]], [[[Bison:b4_percent_define_default]:0.0]]]])])]) # b4_percent_code_get([QUALIFIER]) # -------------------------------- # If any %code blocks for QUALIFIER are defined, emit them beginning with a # comment and ending with synclines and a newline. If QUALIFIER is not # specified or empty, do this for the unqualified %code blocks. Also, record -# the skeleton's usage of QUALIFIER (if specified) by defining -# b4_percent_code_skeleton_qualifiers(QUALIFIER). +# Bison's usage of QUALIFIER (if specified) by defining +# b4_percent_code_bison_qualifiers(QUALIFIER). # # For example, to emit any unqualified %code blocks followed by any %code # blocks for the qualifier foo: @@ -401,7 +420,7 @@ m4_define([b4_percent_define_default], # b4_percent_code_get([[foo]]) m4_define([b4_percent_code_get], [m4_pushdef([b4_macro_name], [[b4_percent_code(]$1[)]])dnl -m4_ifval([$1], [m4_define([b4_percent_code_skeleton_qualifiers(]$1[)])])dnl +m4_ifval([$1], [m4_define([b4_percent_code_bison_qualifiers(]$1[)])])dnl m4_ifdef(b4_macro_name, [b4_comment([m4_if([$#], [0], [[Unqualified %code]], [[%code "]$1["]])[ blocks.]]) @@ -413,24 +432,24 @@ m4_popdef([b4_macro_name])]) # ----------------------------------------------------- # If any %code blocks for QUALIFIER (or unqualified %code blocks if # QUALIFIER is empty) are defined, expand IF-TRUE, else expand IF-FALSE. -# Also, record the skeleton's usage of QUALIFIER (if specified) by defining -# b4_percent_code_skeleton_qualifiers(QUALIFIER). +# Also, record Bison's usage of QUALIFIER (if specified) by defining +# b4_percent_code_bison_qualifiers(QUALIFIER). m4_define([b4_percent_code_ifdef], [m4_ifdef([b4_percent_code(]$1[)], - [m4_ifval([$1], [m4_define([b4_percent_code_skeleton_qualifiers(]$1[)])])$2], + [m4_ifval([$1], [m4_define([b4_percent_code_bison_qualifiers(]$1[)])])$2], [$3])]) -## --------------------------------------------------------- ## -## After processing the skeletons, check that all the user's ## -## %define variables and %code qualifiers were used. ## -## --------------------------------------------------------- ## +## ----------------------------------------------------------- ## +## After processing the skeletons, check that all the user's ## +## %define variables and %code qualifiers were used by Bison. ## +## ----------------------------------------------------------- ## m4_define([b4_check_user_names_wrap], [m4_ifdef([b4_percent_]$1[_user_]$2[s], [b4_check_user_names([[%]$1 $2], [b4_percent_]$1[_user_]$2[s], - [[b4_percent_]$1[_skeleton_]$2[s]])])]) + [[b4_percent_]$1[_bison_]$2[s]])])]) m4_wrap([ b4_check_user_names_wrap([[define]], [[variable]]) diff --git a/doc/bison.texinfo b/doc/bison.texinfo index c39c325b..fe9e4b52 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -4693,14 +4693,32 @@ already defined, so that the debugging facilities are compiled. @deffn {Directive} %define @var{variable} @deffnx {Directive} %define @var{variable} "@var{value}" -Define a variable to adjust Bison's behavior. The possible choices for -@var{variable}, as well as their meanings, depend on the selected target -language and/or the parser skeleton (@pxref{Decl Summary,,%language}). - -Some @var{variable}s may be used as boolean values: in this case, the -skeleton will conventionally treat a @var{value} of @samp{false} as the -boolean variable being false; a @var{value} of @samp{true}, or @var{value} -being omitted altogether, will conversely define the variable as true. +Define a variable to adjust Bison's behavior. +The possible choices for @var{variable}, as well as their meanings, depend on +the selected target language and/or the parser skeleton (@pxref{Decl +Summary,,%language}). + +Bison will warn if a @var{variable} is defined multiple times. + +Omitting @code{"@var{value}"} is always equivalent to specifying it as +@code{""}. + +Some @var{variable}s may be used as booleans. +In this case, Bison will complain if the variable definition does not meet one +of the following four conditions: + +@enumerate +@item @code{"@var{value}"} is @code{"true"} + +@item @code{"@var{value}"} is omitted (or is @code{""}). +This is equivalent to @code{"true"}. + +@item @code{"@var{value}"} is @code{"false"}. + +@item @var{variable} is never defined. +In this case, Bison selects a default value, which may depend on the selected +target language and/or parser skeleton. +@end enumerate @end deffn @deffn {Directive} %defines diff --git a/lib/.cvsignore b/lib/.cvsignore index 7e3729f3..9175bcc4 100644 --- a/lib/.cvsignore +++ b/lib/.cvsignore @@ -63,9 +63,9 @@ strtol.c strtoul.c strverscmp.c strverscmp.h -unistd.h unistd--.h unistd-safer.h +unistd.h unistd_.h unlocked-io.h verify.h diff --git a/src/muscle_tab.c b/src/muscle_tab.c index 5192fc5c..f096dc0b 100644 --- a/src/muscle_tab.c +++ b/src/muscle_tab.c @@ -26,6 +26,7 @@ #include #include +#include "complain.h" #include "files.h" #include "muscle_tab.h" #include "getargs.h" @@ -249,6 +250,207 @@ muscle_find (char const *key) } +void +muscle_boundary_grow (char const *key, boundary bound) +{ + char *extension; + MUSCLE_OBSTACK_SGROW (&muscle_obstack, bound.file); + obstack_1grow (&muscle_obstack, ':'); + obstack_fgrow1 (&muscle_obstack, "%d", bound.line); + obstack_1grow (&muscle_obstack, '.'); + obstack_fgrow1 (&muscle_obstack, "%d", bound.column); + obstack_1grow (&muscle_obstack, '\0'); + extension = obstack_finish (&muscle_obstack); + muscle_grow (key, extension, ""); + obstack_free (&muscle_obstack, extension); +} + +void +muscle_location_grow (char const *key, location loc) +{ + muscle_grow (key, "[[", ""); + muscle_boundary_grow (key, loc.start); + muscle_grow (key, "]], [[", ""); + muscle_boundary_grow (key, loc.end); + muscle_grow (key, "]]", ""); +} + +/* Reverse of muscle_location_grow. */ +static location +muscle_location_decode (char const *key) +{ + location loc; + char const *value = muscle_find_const (key); + aver (value); + aver (*value == '['); + aver (*++value == '['); + while (*++value) + switch (*value) + { + case '$': + aver (*++value == ']'); + aver (*++value == '['); + obstack_sgrow (&muscle_obstack, "$"); + break; + case '@': + switch (*++value) + { + case '@': obstack_sgrow (&muscle_obstack, "@" ); break; + case '{': obstack_sgrow (&muscle_obstack, "[" ); break; + case '}': obstack_sgrow (&muscle_obstack, "]" ); break; + default: aver (false); break; + } + break; + case '[': + aver (false); + break; + case ']': + { + char *boundary_str; + aver (*++value == ']'); + obstack_1grow (&muscle_obstack, '\0'); + boundary_str = obstack_finish (&muscle_obstack); + switch (*++value) + { + case ',': + boundary_set_from_string (&loc.start, boundary_str); + obstack_free (&muscle_obstack, boundary_str); + aver (*++value == ' '); + aver (*++value == '['); + aver (*++value == '['); + break; + case '\0': + boundary_set_from_string (&loc.end, boundary_str); + obstack_free (&muscle_obstack, boundary_str); + return loc; + break; + default: + aver (false); + break; + } + } + break; + default: + obstack_1grow (&muscle_obstack, *value); + break; + } + aver (false); + return loc; +} + +void +muscle_user_name_list_grow (char const *key, char const *user_name, + location loc) +{ + muscle_grow (key, "[[[[", ","); + muscle_grow (key, user_name, ""); + muscle_grow (key, "]], ", ""); + muscle_location_grow (key, loc); + muscle_grow (key, "]]", ""); +} + +#define MUSCLE_USER_NAME_CONVERT(NAME, PREFIX, USER_NAME, SUFFIX) \ +do { \ + char *tmp; \ + size_t length = strlen ((USER_NAME)); \ + tmp = xmalloc (sizeof (PREFIX) - 1 + length + sizeof (SUFFIX)); \ + strcpy (tmp, (PREFIX)); \ + strcpy (tmp + sizeof (PREFIX) - 1, (USER_NAME)); \ + strcpy (tmp + sizeof (PREFIX) - 1 + length, (SUFFIX)); \ + (NAME) = uniqstr_new (tmp); \ + free (tmp); \ +} while (0) + +void +muscle_percent_define_insert (char const *variable, location variable_loc, + char const *value) +{ + char const *name; + char const *loc_name; + + MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")"); + MUSCLE_USER_NAME_CONVERT (loc_name, "percent_define_loc(", variable, ")"); + + if (muscle_find_const (name)) + { + warn_at (variable_loc, _("%s `%s' redefined"), + "%define variable", variable); + warn_at (muscle_location_decode (loc_name), _("previous definition")); + } + MUSCLE_INSERT_STRING (name, value); + + muscle_insert (loc_name, ""); + muscle_location_grow (loc_name, variable_loc); + muscle_user_name_list_grow ("percent_define_user_variables", variable, + variable_loc); +} + +bool +muscle_percent_define_flag_if (char const *variable) +{ + char const *name; + char const *loc_name; + char const *usage_name; + char const *value; + bool result = false; + + MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")"); + MUSCLE_USER_NAME_CONVERT (loc_name, "percent_define_loc(", variable, ")"); + MUSCLE_USER_NAME_CONVERT (usage_name, "percent_define_bison_variables(", + variable, ")"); + + value = muscle_find_const (name); + if (value) + { + if (value[0] == '\0' || 0 == strcmp (value, "true")) + result = true; + else if (0 == strcmp (value, "false")) + result = false; + else if (!muscle_find_const (usage_name)) + complain_at(muscle_location_decode (loc_name), + _("invalid value for %%define boolean variable `%s'"), + variable); + } + else + fatal(_("undefined %%define variable `%s' passed to muscle_percent_define_flag_if"), + variable); + + muscle_insert (usage_name, ""); + + return result; +} + +void +muscle_percent_define_default (char const *variable, char const *value) +{ + char const *name; + char const *loc_name; + MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")"); + MUSCLE_USER_NAME_CONVERT (loc_name, "percent_define_loc(", variable, ")"); + if (!muscle_find_const (name)) + { + location loc; + MUSCLE_INSERT_STRING (name, value); + loc.start.file = loc.end.file = "[Bison:muscle_percent_define_default]"; + loc.start.line = loc.start.column = 0; + loc.end.line = loc.end.column = 0; + muscle_insert (loc_name, ""); + muscle_location_grow (loc_name, loc); + } +} + +void +muscle_percent_code_grow (char const *qualifier, location qualifier_loc, + char const *code, location code_loc) +{ + char const *name; + MUSCLE_USER_NAME_CONVERT (name, "percent_code(", qualifier, ")"); + muscle_code_grow (name, code, code_loc); + muscle_user_name_list_grow ("percent_code_user_qualifiers", qualifier, + qualifier_loc); +} + + /*------------------------------------------------. | Output the definition of ENTRY as a m4_define. | `------------------------------------------------*/ @@ -278,31 +480,3 @@ muscles_m4_output (FILE *out) { hash_do_for_each (muscle_table, muscle_m4_output_processor, out); } - -void -muscle_boundary_grow (char const *key, boundary bound) -{ - char *extension; - MUSCLE_OBSTACK_SGROW (&muscle_obstack, bound.file); - obstack_1grow (&muscle_obstack, ':'); - obstack_fgrow1 (&muscle_obstack, "%d", bound.line); - obstack_1grow (&muscle_obstack, '.'); - obstack_fgrow1 (&muscle_obstack, "%d", bound.column); - obstack_1grow (&muscle_obstack, '\0'); - extension = obstack_finish (&muscle_obstack); - muscle_grow (key, extension, ""); - obstack_free (&muscle_obstack, extension); -} - -void -muscle_grow_user_name_list (char const *key, char const *user_name, - location loc) -{ - muscle_grow (key, "[[[[", ","); - muscle_grow (key, user_name, ""); - muscle_grow (key, "]], [[", ""); - muscle_boundary_grow (key, loc.start); - muscle_grow (key, "]], [[", ""); - muscle_boundary_grow (key, loc.end); - muscle_grow (key, "]]]]", ""); -} diff --git a/src/muscle_tab.h b/src/muscle_tab.h index ed6bd75e..aafaaae5 100644 --- a/src/muscle_tab.h +++ b/src/muscle_tab.h @@ -25,8 +25,8 @@ void muscle_init (void); void muscle_insert (char const *key, char const *value); -char *muscle_find (char const *key); char const *muscle_find_const (char const *key); +char *muscle_find (char const *key); void muscle_free (void); @@ -110,7 +110,9 @@ void muscle_code_grow (const char *key, const char *value, location loc); void muscle_pair_list_grow (const char *muscle, const char *a1, const char *a2); -void muscles_m4_output (FILE *out); +/* In the format `[[file_name:line.column]], [[file_name:line.column]]', append + LOC to MUSCLE. Use digraphs for special characters in each file name. */ +void muscle_location_grow (char const *key, location loc); /* In the format `file_name:line.column', append BOUND to MUSCLE. Use digraphs for special characters in the file name. */ @@ -119,7 +121,36 @@ void muscle_boundary_grow (char const *key, boundary bound); /* Grow KEY for the occurrence of the name USER_NAME at LOC appropriately for use with b4_check_user_names in ../data/bison.m4. USER_NAME is not escaped with digraphs, so it must not contain `[' or `]'. */ -void muscle_grow_user_name_list (char const *key, char const *user_name, +void muscle_user_name_list_grow (char const *key, char const *user_name, location loc); +/* Define the muscle for the %define variable VARIABLE appearing at + VARIABLE_LOC in the grammar file with value VALUE. Warn if VARIABLE is + already defined. Record this as a grammar occurrence of VARIABLE by + invoking muscle_user_name_list_grow. */ +void muscle_percent_define_insert (char const *variable, location variable_loc, + char const *value); + +/* Mimic b4_percent_define_flag_if in ../data/bison.m4 exactly. That is, if + the %define variable VARIABLE is defined to "" or "true", return true. If + it is defined to "false", return false. Complain if it is undefined (a + Bison error since the default value should have been set already) or defined + to any other value (possibly a user error). Also, record Bison's usage of + VARIABLE by defining b4_percent_define_bison_variables(VARIABLE). */ +bool muscle_percent_define_flag_if (char const *variable); + +/* Mimic b4_percent_define_default in ../data/bison.m4 exactly. That is, if + the %define variable VARIABLE is undefined, set its value to VALUE. + Don't record this as a Bison usage of VARIABLE as there's no reason to + suspect that the value has yet influenced the output. */ +void muscle_percent_define_default (char const *variable, char const *value); + +/* Grow the muscle for the %code qualifier QUALIFIER appearing at QUALIFIER_LOC + in the grammar file with code CODE appearing at CODE_LOC. Record this as a + grammar occurrence of VARIABLE by invoking muscle_user_name_list_grow. */ +void muscle_percent_code_grow (char const *qualifier, location qualifier_loc, + char const *code, location code_loc); + +void muscles_m4_output (FILE *out); + #endif /* not MUSCLE_TAB_H_ */ diff --git a/src/parse-gram.c b/src/parse-gram.c index 3b5e6e12..a0a24f2e 100644 --- a/src/parse-gram.c +++ b/src/parse-gram.c @@ -675,17 +675,17 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 210, 210, 218, 220, 224, 225, 235, 236, 250, - 251, 256, 257, 258, 259, 260, 261, 266, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 313, 314, 315, 316, 320, 321, 322, - 326, 333, 340, 344, 348, 353, 376, 377, 381, 393, - 393, 398, 398, 403, 414, 429, 430, 431, 435, 436, - 441, 443, 448, 449, 453, 454, 455, 456, 461, 466, - 471, 477, 483, 494, 495, 504, 505, 511, 512, 513, - 520, 520, 524, 525, 526, 531, 532, 534, 536, 538, - 540, 550, 551, 557, 560, 569, 589, 591, 600, 605, - 606, 611, 618, 620 + 0, 210, 210, 218, 220, 224, 225, 235, 236, 240, + 241, 246, 247, 248, 249, 250, 251, 256, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 303, 304, 305, 306, 310, 311, 312, + 316, 323, 330, 334, 338, 345, 360, 361, 365, 377, + 377, 382, 382, 387, 398, 413, 414, 415, 419, 420, + 425, 427, 432, 433, 437, 438, 439, 440, 445, 450, + 455, 461, 467, 478, 479, 488, 489, 495, 496, 497, + 504, 504, 508, 509, 510, 515, 516, 518, 520, 522, + 524, 534, 535, 541, 544, 553, 573, 575, 584, 589, + 590, 595, 602, 604 }; #endif @@ -1914,31 +1914,21 @@ yyreduce: /* Line 1537 of yacc.c */ #line 237 "parse-gram.y" { - char const name_prefix[] = "percent_define("; - size_t length = strlen ((yyvsp[(2) - (3)].uniqstr)); - char *name = xmalloc (sizeof name_prefix + length + 1); - strcpy (name, name_prefix); - strcpy (name + sizeof name_prefix - 1, (yyvsp[(2) - (3)].uniqstr)); - strcpy (name + sizeof name_prefix - 1 + length, ")"); - if (muscle_find_const (name)) - warn_at ((yylsp[(2) - (3)]), _("%s `%s' redefined"), "%define variable", (yyvsp[(2) - (3)].uniqstr)); - MUSCLE_INSERT_STRING (uniqstr_new (name), (yyvsp[(3) - (3)].chars)); - free (name); - muscle_grow_user_name_list ("percent_define_user_variables", (yyvsp[(2) - (3)].uniqstr), (yylsp[(2) - (3)])); + muscle_percent_define_insert ((yyvsp[(2) - (3)].uniqstr), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].chars)); } break; case 9: /* Line 1537 of yacc.c */ -#line 250 "parse-gram.y" +#line 240 "parse-gram.y" { defines_flag = true; } break; case 10: /* Line 1537 of yacc.c */ -#line 252 "parse-gram.y" +#line 242 "parse-gram.y" { defines_flag = true; spec_defines_file = xstrdup ((yyvsp[(2) - (2)].chars)); @@ -1948,42 +1938,42 @@ yyreduce: case 11: /* Line 1537 of yacc.c */ -#line 256 "parse-gram.y" +#line 246 "parse-gram.y" { error_verbose = true; } break; case 12: /* Line 1537 of yacc.c */ -#line 257 "parse-gram.y" +#line 247 "parse-gram.y" { expected_sr_conflicts = (yyvsp[(2) - (2)].integer); } break; case 13: /* Line 1537 of yacc.c */ -#line 258 "parse-gram.y" +#line 248 "parse-gram.y" { expected_rr_conflicts = (yyvsp[(2) - (2)].integer); } break; case 14: /* Line 1537 of yacc.c */ -#line 259 "parse-gram.y" +#line 249 "parse-gram.y" { spec_file_prefix = (yyvsp[(2) - (2)].chars); } break; case 15: /* Line 1537 of yacc.c */ -#line 260 "parse-gram.y" +#line 250 "parse-gram.y" { spec_file_prefix = (yyvsp[(3) - (3)].chars); } break; case 16: /* Line 1537 of yacc.c */ -#line 262 "parse-gram.y" +#line 252 "parse-gram.y" { nondeterministic_parser = true; glr_parser = true; @@ -1993,7 +1983,7 @@ yyreduce: case 17: /* Line 1537 of yacc.c */ -#line 267 "parse-gram.y" +#line 257 "parse-gram.y" { code_props action; code_props_symbol_action_init (&action, (yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); @@ -2007,105 +1997,105 @@ yyreduce: case 18: /* Line 1537 of yacc.c */ -#line 275 "parse-gram.y" +#line 265 "parse-gram.y" { language_argmatch ((yyvsp[(2) - (2)].chars), 1, &(yylsp[(1) - (2)])); } break; case 19: /* Line 1537 of yacc.c */ -#line 276 "parse-gram.y" +#line 266 "parse-gram.y" { add_param ("lex_param", (yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); } break; case 20: /* Line 1537 of yacc.c */ -#line 277 "parse-gram.y" +#line 267 "parse-gram.y" { locations_flag = true; } break; case 21: /* Line 1537 of yacc.c */ -#line 278 "parse-gram.y" +#line 268 "parse-gram.y" { spec_name_prefix = (yyvsp[(2) - (2)].chars); } break; case 22: /* Line 1537 of yacc.c */ -#line 279 "parse-gram.y" +#line 269 "parse-gram.y" { spec_name_prefix = (yyvsp[(3) - (3)].chars); } break; case 23: /* Line 1537 of yacc.c */ -#line 280 "parse-gram.y" +#line 270 "parse-gram.y" { no_lines_flag = true; } break; case 24: /* Line 1537 of yacc.c */ -#line 281 "parse-gram.y" +#line 271 "parse-gram.y" { nondeterministic_parser = true; } break; case 25: /* Line 1537 of yacc.c */ -#line 282 "parse-gram.y" +#line 272 "parse-gram.y" { spec_outfile = (yyvsp[(2) - (2)].chars); } break; case 26: /* Line 1537 of yacc.c */ -#line 283 "parse-gram.y" +#line 273 "parse-gram.y" { spec_outfile = (yyvsp[(3) - (3)].chars); } break; case 27: /* Line 1537 of yacc.c */ -#line 284 "parse-gram.y" +#line 274 "parse-gram.y" { add_param ("parse_param", (yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); } break; case 28: /* Line 1537 of yacc.c */ -#line 285 "parse-gram.y" +#line 275 "parse-gram.y" { pure_parser = true; } break; case 29: /* Line 1537 of yacc.c */ -#line 286 "parse-gram.y" +#line 276 "parse-gram.y" { push_parser = true; pull_parser = false; } break; case 30: /* Line 1537 of yacc.c */ -#line 287 "parse-gram.y" +#line 277 "parse-gram.y" { push_parser = true; pull_parser = true; } break; case 31: /* Line 1537 of yacc.c */ -#line 288 "parse-gram.y" +#line 278 "parse-gram.y" { version_check (&(yylsp[(2) - (2)]), (yyvsp[(2) - (2)].chars)); } break; case 32: /* Line 1537 of yacc.c */ -#line 290 "parse-gram.y" +#line 280 "parse-gram.y" { char const *skeleton_user = (yyvsp[(2) - (2)].chars); if (strchr (skeleton_user, '/')) @@ -2134,28 +2124,28 @@ yyreduce: case 33: /* Line 1537 of yacc.c */ -#line 313 "parse-gram.y" +#line 303 "parse-gram.y" { token_table_flag = true; } break; case 34: /* Line 1537 of yacc.c */ -#line 314 "parse-gram.y" +#line 304 "parse-gram.y" { report_flag = report_states; } break; case 35: /* Line 1537 of yacc.c */ -#line 315 "parse-gram.y" +#line 305 "parse-gram.y" { yacc_flag = true; } break; case 39: /* Line 1537 of yacc.c */ -#line 323 "parse-gram.y" +#line 313 "parse-gram.y" { grammar_start_symbol_set ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)])); } @@ -2164,7 +2154,7 @@ yyreduce: case 40: /* Line 1537 of yacc.c */ -#line 327 "parse-gram.y" +#line 317 "parse-gram.y" { symbol_list *list; for (list = (yyvsp[(3) - (3)].list); list; list = list->next) @@ -2176,7 +2166,7 @@ yyreduce: case 41: /* Line 1537 of yacc.c */ -#line 334 "parse-gram.y" +#line 324 "parse-gram.y" { symbol_list *list; for (list = (yyvsp[(3) - (3)].list); list; list = list->next) @@ -2188,7 +2178,7 @@ yyreduce: case 42: /* Line 1537 of yacc.c */ -#line 341 "parse-gram.y" +#line 331 "parse-gram.y" { default_prec = true; } @@ -2197,7 +2187,7 @@ yyreduce: case 43: /* Line 1537 of yacc.c */ -#line 345 "parse-gram.y" +#line 335 "parse-gram.y" { default_prec = false; } @@ -2206,8 +2196,10 @@ yyreduce: case 44: /* Line 1537 of yacc.c */ -#line 349 "parse-gram.y" +#line 339 "parse-gram.y" { + /* Do not invoke muscle_percent_code_grow here since it invokes + muscle_user_name_list_grow. */ muscle_code_grow ("percent_code()", (yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)])); code_scanner_last_string_free (); } @@ -2216,39 +2208,31 @@ yyreduce: case 45: /* Line 1537 of yacc.c */ -#line 354 "parse-gram.y" +#line 346 "parse-gram.y" { - char const name_prefix[] = "percent_code("; - size_t length = strlen ((yyvsp[(2) - (3)].uniqstr)); - char *name = xmalloc (sizeof name_prefix + length + 1); - strcpy (name, name_prefix); - strcpy (name + sizeof name_prefix - 1, (yyvsp[(2) - (3)].uniqstr)); - strcpy (name + sizeof name_prefix - 1 + length, ")"); - muscle_code_grow (uniqstr_new (name), (yyvsp[(3) - (3)].chars), (yylsp[(3) - (3)])); - free (name); + muscle_percent_code_grow ((yyvsp[(2) - (3)].uniqstr), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].chars), (yylsp[(3) - (3)])); code_scanner_last_string_free (); - muscle_grow_user_name_list ("percent_code_user_qualifiers", (yyvsp[(2) - (3)].uniqstr), (yylsp[(2) - (3)])); } break; case 46: /* Line 1537 of yacc.c */ -#line 376 "parse-gram.y" +#line 360 "parse-gram.y" {} break; case 47: /* Line 1537 of yacc.c */ -#line 377 "parse-gram.y" +#line 361 "parse-gram.y" { muscle_code_grow ("union_name", (yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 48: /* Line 1537 of yacc.c */ -#line 382 "parse-gram.y" +#line 366 "parse-gram.y" { union_seen = true; muscle_code_grow ("stype", (yyvsp[(3) - (3)].chars), (yylsp[(3) - (3)])); @@ -2259,14 +2243,14 @@ yyreduce: case 49: /* Line 1537 of yacc.c */ -#line 393 "parse-gram.y" +#line 377 "parse-gram.y" { current_class = nterm_sym; } break; case 50: /* Line 1537 of yacc.c */ -#line 394 "parse-gram.y" +#line 378 "parse-gram.y" { current_class = unknown_sym; current_type = NULL; @@ -2276,14 +2260,14 @@ yyreduce: case 51: /* Line 1537 of yacc.c */ -#line 398 "parse-gram.y" +#line 382 "parse-gram.y" { current_class = token_sym; } break; case 52: /* Line 1537 of yacc.c */ -#line 399 "parse-gram.y" +#line 383 "parse-gram.y" { current_class = unknown_sym; current_type = NULL; @@ -2293,7 +2277,7 @@ yyreduce: case 53: /* Line 1537 of yacc.c */ -#line 404 "parse-gram.y" +#line 388 "parse-gram.y" { symbol_list *list; tag_seen = true; @@ -2306,7 +2290,7 @@ yyreduce: case 54: /* Line 1537 of yacc.c */ -#line 415 "parse-gram.y" +#line 399 "parse-gram.y" { symbol_list *list; ++current_prec; @@ -2323,98 +2307,98 @@ yyreduce: case 55: /* Line 1537 of yacc.c */ -#line 429 "parse-gram.y" +#line 413 "parse-gram.y" { (yyval.assoc) = left_assoc; } break; case 56: /* Line 1537 of yacc.c */ -#line 430 "parse-gram.y" +#line 414 "parse-gram.y" { (yyval.assoc) = right_assoc; } break; case 57: /* Line 1537 of yacc.c */ -#line 431 "parse-gram.y" +#line 415 "parse-gram.y" { (yyval.assoc) = non_assoc; } break; case 58: /* Line 1537 of yacc.c */ -#line 435 "parse-gram.y" +#line 419 "parse-gram.y" { current_type = NULL; } break; case 59: /* Line 1537 of yacc.c */ -#line 436 "parse-gram.y" +#line 420 "parse-gram.y" { current_type = (yyvsp[(1) - (1)].uniqstr); tag_seen = true; } break; case 60: /* Line 1537 of yacc.c */ -#line 442 "parse-gram.y" +#line 426 "parse-gram.y" { (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); } break; case 61: /* Line 1537 of yacc.c */ -#line 444 "parse-gram.y" +#line 428 "parse-gram.y" { (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), symbol_list_sym_new ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)]))); } break; case 62: /* Line 1537 of yacc.c */ -#line 448 "parse-gram.y" +#line 432 "parse-gram.y" { (yyval.list) = (yyvsp[(1) - (1)].list); } break; case 63: /* Line 1537 of yacc.c */ -#line 449 "parse-gram.y" +#line 433 "parse-gram.y" { (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].list)); } break; case 64: /* Line 1537 of yacc.c */ -#line 453 "parse-gram.y" +#line 437 "parse-gram.y" { (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); } break; case 65: /* Line 1537 of yacc.c */ -#line 454 "parse-gram.y" +#line 438 "parse-gram.y" { (yyval.list) = symbol_list_type_new ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 66: /* Line 1537 of yacc.c */ -#line 455 "parse-gram.y" +#line 439 "parse-gram.y" { (yyval.list) = symbol_list_default_tagged_new ((yylsp[(1) - (1)])); } break; case 67: /* Line 1537 of yacc.c */ -#line 456 "parse-gram.y" +#line 440 "parse-gram.y" { (yyval.list) = symbol_list_default_tagless_new ((yylsp[(1) - (1)])); } break; case 68: /* Line 1537 of yacc.c */ -#line 462 "parse-gram.y" +#line 446 "parse-gram.y" { current_type = (yyvsp[(1) - (1)].uniqstr); tag_seen = true; @@ -2424,7 +2408,7 @@ yyreduce: case 69: /* Line 1537 of yacc.c */ -#line 467 "parse-gram.y" +#line 451 "parse-gram.y" { symbol_class_set ((yyvsp[(1) - (1)].symbol), current_class, (yylsp[(1) - (1)]), true); symbol_type_set ((yyvsp[(1) - (1)].symbol), current_type, (yylsp[(1) - (1)])); @@ -2434,7 +2418,7 @@ yyreduce: case 70: /* Line 1537 of yacc.c */ -#line 472 "parse-gram.y" +#line 456 "parse-gram.y" { symbol_class_set ((yyvsp[(1) - (2)].symbol), current_class, (yylsp[(1) - (2)]), true); symbol_type_set ((yyvsp[(1) - (2)].symbol), current_type, (yylsp[(1) - (2)])); @@ -2445,7 +2429,7 @@ yyreduce: case 71: /* Line 1537 of yacc.c */ -#line 478 "parse-gram.y" +#line 462 "parse-gram.y" { symbol_class_set ((yyvsp[(1) - (2)].symbol), current_class, (yylsp[(1) - (2)]), true); symbol_type_set ((yyvsp[(1) - (2)].symbol), current_type, (yylsp[(1) - (2)])); @@ -2456,7 +2440,7 @@ yyreduce: case 72: /* Line 1537 of yacc.c */ -#line 484 "parse-gram.y" +#line 468 "parse-gram.y" { symbol_class_set ((yyvsp[(1) - (3)].symbol), current_class, (yylsp[(1) - (3)]), true); symbol_type_set ((yyvsp[(1) - (3)].symbol), current_type, (yylsp[(1) - (3)])); @@ -2468,7 +2452,7 @@ yyreduce: case 79: /* Line 1537 of yacc.c */ -#line 514 "parse-gram.y" +#line 498 "parse-gram.y" { yyerrok; } @@ -2477,77 +2461,77 @@ yyreduce: case 80: /* Line 1537 of yacc.c */ -#line 520 "parse-gram.y" +#line 504 "parse-gram.y" { current_lhs = (yyvsp[(1) - (1)].symbol); current_lhs_location = (yylsp[(1) - (1)]); } break; case 82: /* Line 1537 of yacc.c */ -#line 524 "parse-gram.y" +#line 508 "parse-gram.y" { grammar_current_rule_end ((yylsp[(1) - (1)])); } break; case 83: /* Line 1537 of yacc.c */ -#line 525 "parse-gram.y" +#line 509 "parse-gram.y" { grammar_current_rule_end ((yylsp[(3) - (3)])); } break; case 85: /* Line 1537 of yacc.c */ -#line 531 "parse-gram.y" +#line 515 "parse-gram.y" { grammar_current_rule_begin (current_lhs, current_lhs_location); } break; case 86: /* Line 1537 of yacc.c */ -#line 533 "parse-gram.y" +#line 517 "parse-gram.y" { grammar_current_rule_symbol_append ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)])); } break; case 87: /* Line 1537 of yacc.c */ -#line 535 "parse-gram.y" +#line 519 "parse-gram.y" { grammar_current_rule_action_append ((yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); } break; case 88: /* Line 1537 of yacc.c */ -#line 537 "parse-gram.y" +#line 521 "parse-gram.y" { grammar_current_rule_prec_set ((yyvsp[(3) - (3)].symbol), (yylsp[(3) - (3)])); } break; case 89: /* Line 1537 of yacc.c */ -#line 539 "parse-gram.y" +#line 523 "parse-gram.y" { grammar_current_rule_dprec_set ((yyvsp[(3) - (3)].integer), (yylsp[(3) - (3)])); } break; case 90: /* Line 1537 of yacc.c */ -#line 541 "parse-gram.y" +#line 525 "parse-gram.y" { grammar_current_rule_merge_set ((yyvsp[(3) - (3)].uniqstr), (yylsp[(3) - (3)])); } break; case 92: /* Line 1537 of yacc.c */ -#line 551 "parse-gram.y" +#line 535 "parse-gram.y" { (yyval.uniqstr) = uniqstr_new ((yyvsp[(1) - (1)].chars)); } break; case 93: /* Line 1537 of yacc.c */ -#line 557 "parse-gram.y" +#line 541 "parse-gram.y" { (yyval.chars) = ""; } @@ -2556,7 +2540,7 @@ yyreduce: case 95: /* Line 1537 of yacc.c */ -#line 570 "parse-gram.y" +#line 554 "parse-gram.y" { code_props plain_code; (yyvsp[(1) - (1)].code)[strlen ((yyvsp[(1) - (1)].code)) - 1] = '\n'; @@ -2570,14 +2554,14 @@ yyreduce: case 96: /* Line 1537 of yacc.c */ -#line 590 "parse-gram.y" +#line 574 "parse-gram.y" { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 97: /* Line 1537 of yacc.c */ -#line 592 "parse-gram.y" +#line 576 "parse-gram.y" { (yyval.symbol) = symbol_get (char_name ((yyvsp[(1) - (1)].character)), (yylsp[(1) - (1)])); symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false); @@ -2588,14 +2572,14 @@ yyreduce: case 98: /* Line 1537 of yacc.c */ -#line 600 "parse-gram.y" +#line 584 "parse-gram.y" { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 101: /* Line 1537 of yacc.c */ -#line 612 "parse-gram.y" +#line 596 "parse-gram.y" { (yyval.symbol) = symbol_get (quotearg_style (c_quoting_style, (yyvsp[(1) - (1)].chars)), (yylsp[(1) - (1)])); symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false); @@ -2605,7 +2589,7 @@ yyreduce: case 103: /* Line 1537 of yacc.c */ -#line 621 "parse-gram.y" +#line 605 "parse-gram.y" { code_props plain_code; code_props_plain_init (&plain_code, (yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)])); @@ -2619,7 +2603,7 @@ yyreduce: /* Line 1537 of yacc.c */ -#line 2623 "parse-gram.c" +#line 2607 "parse-gram.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -2838,7 +2822,7 @@ yyreturn: /* Line 1537 of yacc.c */ -#line 631 "parse-gram.y" +#line 615 "parse-gram.y" diff --git a/src/parse-gram.y b/src/parse-gram.y index 86c1dece..df92d642 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -235,17 +235,7 @@ prologue_declaration: | "%debug" { debug_flag = true; } | "%define" variable content.opt { - char const name_prefix[] = "percent_define("; - size_t length = strlen ($2); - char *name = xmalloc (sizeof name_prefix + length + 1); - strcpy (name, name_prefix); - strcpy (name + sizeof name_prefix - 1, $2); - strcpy (name + sizeof name_prefix - 1 + length, ")"); - if (muscle_find_const (name)) - warn_at (@2, _("%s `%s' redefined"), "%define variable", $2); - MUSCLE_INSERT_STRING (uniqstr_new (name), $3); - free (name); - muscle_grow_user_name_list ("percent_define_user_variables", $2, @2); + muscle_percent_define_insert ($2, @2, $3); } | "%defines" { defines_flag = true; } | "%defines" STRING @@ -347,21 +337,15 @@ grammar_declaration: } | "%code" braceless { + /* Do not invoke muscle_percent_code_grow here since it invokes + muscle_user_name_list_grow. */ muscle_code_grow ("percent_code()", $2, @2); code_scanner_last_string_free (); } | "%code" ID braceless { - char const name_prefix[] = "percent_code("; - size_t length = strlen ($2); - char *name = xmalloc (sizeof name_prefix + length + 1); - strcpy (name, name_prefix); - strcpy (name + sizeof name_prefix - 1, $2); - strcpy (name + sizeof name_prefix - 1 + length, ")"); - muscle_code_grow (uniqstr_new (name), $3, @3); - free (name); + muscle_percent_code_grow ($2, @2, $3, @3); code_scanner_last_string_free (); - muscle_grow_user_name_list ("percent_code_user_qualifiers", $2, @2); } ; diff --git a/tests/input.at b/tests/input.at index d21ca41d..d0bdcbdd 100644 --- a/tests/input.at +++ b/tests/input.at @@ -811,7 +811,9 @@ start: ; AT_CHECK([[bison input.y]], [0], [], [[input.y:2.9-11: warning: %define variable `var' redefined +input.y:1.9-11: warning: previous definition input.y:3.10-12: warning: %define variable `var' redefined +input.y:2.9-11: warning: previous definition input.y:1.9-11: warning: %define variable `var' is not used input.y:2.9-11: warning: %define variable `var' is not used input.y:3.10-12: warning: %define variable `var' is not used @@ -836,7 +838,7 @@ start: ; ]]) AT_CHECK([[bison Input.y]], [1], [], -[[Input.y: invalid value for %define variable `public' +[[Input.y:2.9-14: invalid value for %define boolean variable `public' ]]) AT_CLEANUP diff --git a/tests/skeletons.at b/tests/skeletons.at index 281986d4..36a82b3f 100644 --- a/tests/skeletons.at +++ b/tests/skeletons.at @@ -19,10 +19,10 @@ AT_BANNER([[Skeleton Support.]]) ## ------------------------------ ## -## relative skeleton file names. ## +## Relative skeleton file names. ## ## ------------------------------ ## -AT_SETUP([[relative skeleton file names]]) +AT_SETUP([[Relative skeleton file names]]) AT_CHECK([[mkdir tmp]]) @@ -79,10 +79,10 @@ AT_CLEANUP ## ------------------------------- ## -## installed skeleton file names. ## +## Installed skeleton file names. ## ## ------------------------------- ## -AT_SETUP([[installed skeleton file names]]) +AT_SETUP([[Installed skeleton file names]]) m4_pushdef([AT_GRAM], [[%{ @@ -141,3 +141,31 @@ AT_PARSER_CHECK([[./input-gram]], [[1]], [], m4_popdef([AT_GRAM]) AT_CLEANUP + + +## ------------------------------------------------------ ## +## %define boolean variables: invalid skeleton defaults. ## +## ------------------------------------------------------ ## + +AT_SETUP([[%define boolean variables: invalid skeleton defaults]]) + +AT_CHECK([[mkdir tmp]]) + +AT_DATA([[skel.c]], +[[b4_percent_define_default([[foo]], [[bogus value]]) +b4_percent_define_flag_if([[foo]]) +]]) + +AT_DATA([[input.y]], +[[%skeleton "./skel.c" +%% +start: ; +]]) + +AT_CHECK([[bison input.y]], [[1]], [[]], +[[[Bison:b4_percent_define_default]:0.0: invalid value for %define boolean variable `foo' +]]) + +AT_CLEANUP + + -- 2.45.2