]> git.saurik.com Git - bison.git/commitdiff
Miscellaneous %define and %code cleanup.
authorJoel E. Denny <jdenny@ces.clemson.edu>
Fri, 2 Mar 2007 06:26:28 +0000 (06:26 +0000)
committerJoel E. Denny <jdenny@ces.clemson.edu>
Fri, 2 Mar 2007 06:26:28 +0000 (06:26 +0000)
* 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
data/bison.m4
doc/bison.texinfo
lib/.cvsignore
src/muscle_tab.c
src/muscle_tab.h
src/parse-gram.c
src/parse-gram.y
tests/input.at
tests/skeletons.at

index 109930a8de0310c6733384a386608d331eb154c5..b4f796640bac22efbdcbdf9c25e513248e5c21ba 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,57 @@
+2007-03-02  Joel E. Denny  <jdenny@ces.clemson.edu>
+
+       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  <jdenny@ces.clemson.edu>
 
        * src/print.c (lookahead_set, state_default_rule): Remove.
index f5a1a7c97f5fae0c1c2e00ddb36569153b6db2dc..0aa1efdc764228c740d597fea9e34cae8addbf34 100644 (file)
@@ -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]])
index c39c325b7519f9baabd1b89b5a596c45e53540dd..fe9e4b5283c90c7d1df75cd7fa2c76b3b0d9e68e 100644 (file)
@@ -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
index 7e3729f370b035f2f213157aed7f06bb7f30a836..9175bcc47a044398a95f527201b049919440656d 100644 (file)
@@ -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
index 5192fc5c940b95ddf1fc062cb8cb488586205d11..f096dc0bc539f2595b1d8405bd57fb511d77a660 100644 (file)
@@ -26,6 +26,7 @@
 #include <hash.h>
 #include <quotearg.h>
 
+#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, "]]]]", "");
-}
index ed6bd75e40edf232e594e7ba9b4130c1c86c6c54..aafaaae539a4dbb5f7c92c8ba42d4394fc62ea35 100644 (file)
@@ -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_ */
index 3b5e6e122a81fc11a90ea5e7a60be45b339e9ce2..a0a24f2e054e7f095d73b51c1146728ad077c4f0 100644 (file)
@@ -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"
 
 
 
index 86c1decea0f16c39efde6fb729773c06748646bb..df92d6421ed0d48c2271bcb8a9b80355e83a5960 100644 (file)
@@ -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);
     }
 ;
 
index d21ca41dacf0f8d74539db14b454ddfba3bf67d9..d0bdcbdd61b9a2b2e36c47b574d7a91a4cefe70f 100644 (file)
@@ -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
index 281986d42dd01d3820329e924e306aef35e2dc92..36a82b3f0e8dca826ef5216f41ff465f77f94fc2 100644 (file)
 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
+
+