Merge branch 'maint'
authorAkim Demaille <akim@lrde.epita.fr>
Fri, 12 Oct 2012 10:39:52 +0000 (12:39 +0200)
committerAkim Demaille <akim@lrde.epita.fr>
Fri, 12 Oct 2012 10:49:57 +0000 (12:49 +0200)
* origin/maint:
  tests: check %no-lines
  tests: minor simplification
  graphs: stylistic changes.
  graphs: minor style changes
  graphs: show reductions
  graphs: style: prefix state number with "state"
  graphs: style: use left justification for states
  graphs: style: prefix rules and change shapes
  obstack: import obstack_finish0 from master
  c++: api.location.type
  muscles: a function for backward compatibility
  maint: more macros

Conflicts:
data/glr.cc
data/java.m4
data/lalr1.cc
doc/bison.texi
src/muscle-tab.c
src/system.h
tests/calc.at

13 files changed:
1  2 
NEWS
data/c++.m4
data/glr.cc
data/java.m4
data/lalr1.cc
doc/bison.texi
src/muscle-tab.c
src/print_graph.c
src/system.h
tests/calc.at
tests/headers.at
tests/java.at
tests/local.at

diff --cc NEWS
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -301,6 -65,21 +301,21 @@@ GNU Bison NEW
    "function declared 'noreturn' should not return") have also been
    addressed.
  
 -  and position files: let one of them generate them, and let the others
 -  simply resue these types and files.
+ ** New %define variable: api.location.type (glr.cc, lalr1.cc)
+   The %define variable api.location.type defines the name of the type to use
+   for locations.  When defined, Bison no longer generates the position.hh
+   and location.hh files, nor does the parser will include them: the user is
+   then responsible to define her type.
+   This can be used in programs with several parsers to factor their location
++  and position files: let one of them generate them, and the others just use
++  them.
+   This feature was actually introduced, but not documented, in Bison 2.5,
+   under the name "location_type" (which is maintained for backward
+   compatibility).
  * Noteworthy changes in release 2.6.2 (2012-08-03) [stable]
  
  ** Bug fixes
diff --cc data/c++.m4
@@@ -28,11 -29,10 +28,11 @@@ b4_percent_define_default([[parser_clas
  # Don't do that so that we remember whether we're using a user
  # request, or the default value.
  #
- # b4_percent_define_default([[location_type]], [[location]])
+ # b4_percent_define_default([[api.location.type]], [[location]])
  
  b4_percent_define_default([[filename_type]], [[std::string]])
 -b4_percent_define_default([[namespace]], m4_defn([b4_prefix]))
 +b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
 +
  b4_percent_define_default([[global_tokens_and_yystype]], [[false]])
  b4_percent_define_default([[define_location_comparison]],
                            [m4_if(b4_percent_define_get([[filename_type]]),
@@@ -105,257 -103,6 +105,257 @@@ m4_define([b4_token_enums]
  ## Semantic Values.  ##
  ## ----------------- ##
  
-     typedef b4_percent_define_get([[location_type]],
 +# b4_semantic_type_declare
 +# ------------------------
 +# Declare semantic_type.
 +m4_define([b4_semantic_type_declare],
 +[    /// Symbol semantic values.
 +m4_ifdef([b4_stype],
 +[    union semantic_type
 +    {b4_user_stype
 +    };],
 +[m4_if(b4_tag_seen_flag, 0,
 +[[    typedef int semantic_type;]],
 +[[    typedef ]b4_api_PREFIX[STYPE semantic_type;]])])])
 +
 +
 +# b4_public_types_declare
 +# -----------------------
 +# Define the public types: token, semantic value, location, and so forth.
 +# Depending on %define token_lex, may be output in the header or source file.
 +m4_define([b4_public_types_declare],
 +[[#ifndef ]b4_api_PREFIX[STYPE
 +]b4_semantic_type_declare[
 +#else
 +    typedef ]b4_api_PREFIX[STYPE semantic_type;
 +#endif]b4_locations_if([
 +    /// Symbol locations.
++    typedef b4_percent_define_get([[api.location.type]],
 +                                  [[location]]) location_type;])[
 +
 +    /// Syntax errors thrown from user actions.
 +    struct syntax_error : std::runtime_error
 +    {
 +      syntax_error (]b4_locations_if([const location_type& l, ])[const std::string& m);]b4_locations_if([
 +      location_type location;])[
 +    };
 +
 +    /// Tokens.
 +    struct token
 +    {
 +      ]b4_token_enums[
 +    };
 +
 +    /// Token type.
 +    typedef token::yytokentype token_type;
 +
 +    /// A complete symbol, with its type.
 +    template <typename Exact>
 +    struct symbol_base_type
 +    {
 +      /// Default constructor.
 +      inline symbol_base_type ();
 +
 +      /// Constructor.]b4_locations_if([
 +      inline symbol_base_type (const location_type& l);])[
 +      inline symbol_base_type (]b4_join(
 +        [const semantic_type& v],
 +        b4_locations_if([const location_type& l]))[);
 +
 +      /// Return this with its exact type.
 +      const Exact& self () const;
 +      Exact& self ();
 +
 +      /// Return the type of this symbol.
 +      int type_get () const;
 +
 +      /// The semantic value.
 +      semantic_type value;]b4_locations_if([
 +
 +      /// The location.
 +      location_type location;])[
 +    };
 +
 +    /// External form of a symbol: its type and attributes.
 +    struct symbol_type : symbol_base_type<symbol_type>
 +    {
 +      /// The parent class.
 +      typedef symbol_base_type<symbol_type> super_type;
 +
 +      /// Default constructor.
 +      inline symbol_type ();
 +
 +      /// Constructor for tokens with semantic value.
 +      inline symbol_type (]b4_join([token_type t],
 +                                   [const semantic_type& v],
 +                                   b4_locations_if([const location_type& l]))[);
 +
 +      /// Constructor for valueless tokens.
 +      inline symbol_type (]b4_join([token_type t],
 +                                   b4_locations_if([const location_type& l]))[);
 +
 +      /// The symbol type.
 +      int type;
 +
 +      /// The symbol type.
 +      inline int type_get_ () const;
 +
 +      /// The token.
 +      inline token_type token () const;
 +    };
 +]b4_symbol_constructor_declare])
 +
 +
 +# b4_public_types_define
 +# ----------------------
 +# Provide the implementation needed by the public types.
 +m4_define([b4_public_types_define],
 +[[  inline
 +  ]b4_parser_class_name[::syntax_error::syntax_error (]b4_locations_if([const location_type& l, ])[const std::string& m)
 +    : std::runtime_error (m)]b4_locations_if([
 +    , location (l)])[
 +  {}
 +
 +  // symbol_base_type.
 +  template <typename Exact>
 +  inline
 +  ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type ()
 +    : value()]b4_locations_if([
 +    , location()])[
 +  {
 +  }]b4_locations_if([[
 +
 +  template <typename Exact>
 +  inline
 +  ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type (const location_type& l)
 +    : value()
 +    , location(l)
 +  {
 +  }]])[
 +
 +  template <typename Exact>
 +  inline
 +  ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type (]b4_join(
 +          [const semantic_type& v],
 +          b4_locations_if([const location_type& l]))[)
 +    : value(v)]b4_locations_if([
 +    , location(l)])[
 +  {
 +  }
 +
 +  template <typename Exact>
 +  inline
 +  const Exact&
 +  ]b4_parser_class_name[::symbol_base_type<Exact>::self () const
 +  {
 +    return static_cast<const Exact&>(*this);
 +  }
 +
 +  template <typename Exact>
 +  inline
 +  Exact&
 +  ]b4_parser_class_name[::symbol_base_type<Exact>::self ()
 +  {
 +    return static_cast<Exact&>(*this);
 +  }
 +
 +  template <typename Exact>
 +  inline
 +  int
 +  ]b4_parser_class_name[::symbol_base_type<Exact>::type_get () const
 +  {
 +    return self ().type_get_ ();
 +  }
 +
 +  // symbol_type.
 +  inline
 +  ]b4_parser_class_name[::symbol_type::symbol_type ()
 +    : super_type ()
 +    , type ()
 +  {
 +  }
 +
 +  inline
 +  ]b4_parser_class_name[::symbol_type::symbol_type (]b4_join(
 +                [token_type t],
 +                b4_locations_if([const location_type& l]))[)
 +    : super_type (]b4_locations_if([l])[)
 +    , type (yytranslate_ (t))
 +  {
 +  }
 +
 +  inline
 +  ]b4_parser_class_name[::symbol_type::symbol_type (]b4_join(
 +                 [token_type t],
 +                 [const semantic_type& v],
 +                 b4_locations_if([const location_type& l]))[)
 +    : super_type (v]b4_locations_if([, l])[)
 +    , type (yytranslate_ (t))
 +  {
 +  }
 +
 +  inline
 +  int
 +  ]b4_parser_class_name[::symbol_type::type_get_ () const
 +  {
 +    return type;
 +  }
 +]b4_lex_symbol_if([[
 +  inline
 +  ]b4_parser_class_name[::token_type
 +  ]b4_parser_class_name[::symbol_type::token () const
 +  {
 +    // YYTOKNUM[NUM] -- (External) token number corresponding to the
 +    // (internal) symbol number NUM (which must be that of a token).  */
 +    static
 +    const ]b4_int_type_for([b4_toknum])[
 +    yytoken_number_[] =
 +    {
 +  ]b4_toknum[
 +    };
 +    return static_cast<token_type> (yytoken_number_[type]);
 +  }
 +]])[]dnl
 +b4_symbol_constructor_define])
 +
 +
 +# b4_symbol_constructor_declare
 +# b4_symbol_constructor_define
 +# -----------------------------
 +# Declare/define symbol constructors for all the value types.
 +# Use at class-level.  Redefined in variant.hh.
 +m4_define([b4_symbol_constructor_declare], [])
 +m4_define([b4_symbol_constructor_define], [])
 +
 +
 +# b4_yytranslate_define
 +# ---------------------
 +# Define yytranslate_.  Sometimes used in the header file,
 +# sometimes in the cc file.
 +m4_define([b4_yytranslate_define],
 +[[  // Symbol number corresponding to token number t.
 +  ]b4_parser_class_name[::token_number_type
 +  ]b4_parser_class_name[::yytranslate_ (]b4_lex_symbol_if([token_type],
 +                                                          [int])[ t)
 +  {
 +    static
 +    const token_number_type
 +    translate_table[] =
 +    {
 +]b4_translate[
 +    };
 +    const unsigned int user_token_number_max_ = ]b4_user_token_number_max[;
 +    const token_number_type undef_token_ = ]b4_undef_token_number[;
 +
 +    if (static_cast<int>(t) <= yyeof_)
 +      return yyeof_;
 +    else if (static_cast<unsigned int> (t) <= user_token_number_max_)
 +      return translate_table[t];
 +    else
 +      return undef_token_;
 +  }
 +]])
 +
  
  # b4_lhs_value([TYPE])
  # --------------------
diff --cc data/glr.cc
  #   user must initialize the first positions (in particular the
  #   filename member).
  
 -# We require a pure interface using locations.
 -m4_define([b4_locations_flag], [1])
 +# We require a pure interface.
  m4_define([b4_pure_flag],      [1])
  
 -# The header is mandatory.
 -b4_defines_if([],
 -              [b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
 -
  m4_include(b4_pkgdatadir/[c++.m4])
- b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
 -b4_percent_define_ifdef([[api.location.type]], [],
 -                        [m4_include(b4_pkgdatadir/[location.cc])])
++b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
 +                [m4_include(b4_pkgdatadir/[location.cc])])])
  
  m4_define([b4_parser_class_name],
            [b4_percent_define_get([[parser_class_name]])])
@@@ -204,32 -211,39 +204,32 @@@ m4_pushdef([b4_parse_param], m4_defn([b
  
  #endif
  ]m4_popdef([b4_parse_param])dnl
 -b4_namespace_close])
 -
 -
 -# Let glr.c believe that the user arguments include the parser itself.
 -m4_ifset([b4_parse_param],
 -[m4_pushdef([b4_parse_param],
 -            [[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]],]
 -m4_defn([b4_parse_param]))],
 -[m4_pushdef([b4_parse_param],
 -            [[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]]])
 +b4_namespace_close
  ])
 -m4_include(b4_pkgdatadir/[glr.c])
 -m4_popdef([b4_parse_param])
 -
 -m4_divert_push(0)
 -@output(b4_spec_defines_file@)@
 -b4_copyright([Skeleton interface for Bison GLR parsers in C++],
 -             [2002-2006, 2009-2012])[
  
 -/* C++ GLR parser skeleton written by Akim Demaille.  */
 -
 -]b4_cpp_guard_open([b4_spec_defines_file])[
 -
 -]b4_percent_code_get([[requires]])[
 +# b4_shared_declarations
 +# ----------------------
 +# Declaration that might either go into the header (if --defines)
 +# or open coded in the parser body.
 +m4_define([b4_shared_declarations],
 +[dnl In this section, the parse params are the original parse_params.
 +m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
 +b4_percent_code_get([[requires]])[
  
 -# include <string>
 -# include <iostream>
 -]b4_percent_define_ifdef([[api.location.type]], [],
 -                         [[# include "location.hh"]])[
 +#include <stdexcept>
 +#include <string>
 +#include <iostream>]b4_defines_if([
- b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
++b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
 +                                         [[#include "location.hh"]])])])[
  
  ]b4_YYDEBUG_define[
  
  ]b4_namespace_open[
- [b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
 +]b4_defines_if([],
++[b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
 +                                          [b4_position_define
 +b4_location_define])])])[
 +
    /// A Bison parser.
    class ]b4_parser_class_name[
    {
diff --cc data/java.m4
@@@ -185,22 -160,19 +185,22 @@@ b4_percent_define_default([[stype]], [[
  # %name-prefix
  m4_define_default([b4_prefix], [[YY]])
  
 -b4_percent_define_default([[parser_class_name]], [b4_prefix[]Parser])])
 +b4_percent_define_default([[parser_class_name]], [b4_prefix[]Parser])
  m4_define([b4_parser_class_name], [b4_percent_define_get([[parser_class_name]])])
  
 -b4_percent_define_default([[lex_throws]], [[java.io.IOException]])])
 +b4_percent_define_default([[lex_throws]], [[java.io.IOException]])
  m4_define([b4_lex_throws], [b4_percent_define_get([[lex_throws]])])
  
 -b4_percent_define_default([[throws]], [])])
 +b4_percent_define_default([[throws]], [])
  m4_define([b4_throws], [b4_percent_define_get([[throws]])])
  
 -b4_percent_define_default([[api.location.type]], [Location])])
 +b4_percent_define_default([[init_throws]], [])
 +m4_define([b4_init_throws], [b4_percent_define_get([[init_throws]])])
 +
- b4_percent_define_default([[location_type]], [Location])
- m4_define([b4_location_type], [b4_percent_define_get([[location_type]])])
++b4_percent_define_default([[api.location.type]], [Location])
+ m4_define([b4_location_type], [b4_percent_define_get([[api.location.type]])])
  
 -b4_percent_define_default([[position_type]], [Position])])
 +b4_percent_define_default([[position_type]], [Position])
  m4_define([b4_position_type], [b4_percent_define_get([[position_type]])])
  
  
diff --cc data/lalr1.cc
  
  m4_include(b4_pkgdatadir/[c++.m4])
  
 -m4_define([b4_parser_class_name],
 -          [b4_percent_define_get([[parser_class_name]])])
  
 -# The header is mandatory.
 -b4_defines_if([],
 -              [b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
 +# b4_integral_parser_table_declare(TABLE-NAME, CONTENT, COMMENT)
 +# --------------------------------------------------------------
 +# Declare "parser::yy<TABLE-NAME>_" which contents is CONTENT.
 +m4_define([b4_integral_parser_table_declare],
 +[m4_ifval([$3], [b4_comment([$3], [  ])
 +])dnl
 +  static const b4_int_type_for([$2]) yy$1_[[]];dnl
 +])
 +
 +# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
 +# -------------------------------------------------------------
 +# Define "parser::yy<TABLE-NAME>_" which contents is CONTENT.
 +m4_define([b4_integral_parser_table_define],
 +[  const b4_int_type_for([$2])
 +  b4_parser_class_name::yy$1_[[]] =
 +  {
 +  $2
 +  };dnl
 +])
 +
 +
 +# b4_symbol_value_template(VAL, [TYPE])
 +# -------------------------------------
 +# Same as b4_symbol_value, but used in a template method.  It makes
 +# a difference when using variants.
 +m4_copy([b4_symbol_value], [b4_symbol_value_template])
 +
 +
 +# b4_lhs_value([TYPE])
 +# --------------------
 +# Expansion of $<TYPE>$.
 +m4_define([b4_lhs_value],
 +          [b4_symbol_value([yylhs.value], [$1])])
 +
 +
 +# b4_lhs_location()
 +# -----------------
 +# Expansion of @$.
 +m4_define([b4_lhs_location],
 +          [yylhs.location])
 +
 +
 +# b4_rhs_data(RULE-LENGTH, NUM)
 +# -----------------------------
 +# Return the data corresponding to the symbol #NUM, where the current
 +# rule has RULE-LENGTH symbols on RHS.
 +m4_define([b4_rhs_data],
 +          [yystack_@{b4_subtract($@)@}])
 +
 +
 +# b4_rhs_state(RULE-LENGTH, NUM)
 +# ------------------------------
 +# The state corresponding to the symbol #NUM, where the current
 +# rule has RULE-LENGTH symbols on RHS.
 +m4_define([b4_rhs_state],
 +          [b4_rhs_data([$1], [$2]).state])
 +
 +
 +# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
 +# --------------------------------------
 +# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
 +# symbols on RHS.
 +m4_define([b4_rhs_value],
 +          [b4_symbol_value([b4_rhs_data([$1], [$2]).value], [$3])])
 +
 +
 +# b4_rhs_location(RULE-LENGTH, NUM)
 +# ---------------------------------
 +# Expansion of @NUM, where the current rule has RULE-LENGTH symbols
 +# on RHS.
 +m4_define([b4_rhs_location],
 +          [b4_rhs_data([$1], [$2]).location])
 +
 +
 +# b4_symbol_action(SYMBOL-NUM, KIND)
 +# ----------------------------------
 +# Run the action KIND (destructor or printer) for SYMBOL-NUM.
 +# Same as in C, but using references instead of pointers.
 +m4_define([b4_symbol_action],
 +[b4_symbol_if([$1], [has_$2],
 +[m4_pushdef([b4_symbol_value], m4_defn([b4_symbol_value_template]))[]dnl
 +b4_dollar_pushdef([yysym.value],
 +                   b4_symbol_if([$1], [has_type],
 +                                [m4_dquote(b4_symbol([$1], [type]))]),
 +                   [yysym.location])dnl
 +      b4_symbol_case_([$1])
 +b4_syncline([b4_symbol([$1], [$2_line])], ["b4_symbol([$1], [$2_file])"])
 +        b4_symbol([$1], [$2])
 +b4_syncline([@oline@], [@ofile@])
 +        break;
  
 -b4_percent_define_ifdef([[api.location.type]], [],
 -  [# Backward compatibility.
 -  m4_define([b4_location_constructors])
 -  m4_include(b4_pkgdatadir/[location.cc])])
 -m4_include(b4_pkgdatadir/[stack.hh])
 +m4_popdef([b4_symbol_value])[]dnl
 +b4_dollar_popdef[]dnl
 +])])
  
 -# We do want M4 expansion after # for CPP macros.
 -m4_changecom()
 -m4_divert_push(0)dnl
 -b4_defines_if(
 -[@output(b4_spec_defines_file@)@
 -b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++],
 -             [2002-2012])
 -[
 -/**
 - ** \file ]b4_spec_defines_file[
 - ** Define the ]b4_namespace_ref[::parser class.
 - */
 -
 -/* C++ LALR(1) parser skeleton written by Akim Demaille.  */
  
 -]b4_cpp_guard_open([b4_spec_defines_file])[
 +m4_pushdef([b4_copyright_years],
 +           [2002-2012])
  
 -]b4_percent_code_get([[requires]])[
 +m4_define([b4_parser_class_name],
 +          [b4_percent_define_get([[parser_class_name]])])
  
- b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
 -#include <string>
 -#include <iostream>
 -#include "stack.hh"
 -]b4_percent_define_ifdef([[api.location.type]], [],
 -                         [[#include "location.hh"]])[
++b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
 +  [# Backward compatibility.
 +   m4_define([b4_location_constructors])
 +   m4_include(b4_pkgdatadir/[location.cc])])])
 +m4_include(b4_pkgdatadir/[stack.hh])
 +b4_variant_if([m4_include(b4_pkgdatadir/[variant.hh])])
 +
 +# b4_shared_declarations
 +# ----------------------
 +# Declaration that might either go into the header (if --defines)
 +# or open coded in the parser body.
 +m4_define([b4_shared_declarations],
 +[b4_percent_code_get([[requires]])[
 +]b4_parse_assert_if([# include <cassert>])[
 +# include <deque>
 +# include <iostream>
 +# include <stdexcept>
 +# include <string>]b4_defines_if([[
 +# include "stack.hh"
- ]b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
++]b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
 +                                          [[# include "location.hh"]])])])[
  
  ]b4_YYDEBUG_define[
  
  ]b4_namespace_open[
  
- b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
 +]b4_defines_if([],
 +[b4_stack_define
++b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
 +                                         [b4_position_define
 +b4_location_define])])])[
 +
 +]b4_variant_if([b4_variant_define])[
 +
    /// A Bison parser.
    class ]b4_parser_class_name[
    {
diff --cc doc/bison.texi
@@@ -5420,62 -5325,26 +5421,78 @@@ Summary,,%skeleton})
  Unaccepted @var{variable}s produce an error.
  Some of the accepted @var{variable}s are:
  
 -@itemize @bullet
 +@table @code
 +@c ================================================== api.namespace
 +@item api.namespace
 +@findex %define api.namespace
 +@itemize
 +@item Languages(s): C++
 +
 +@item Purpose: Specify the namespace for the parser class.
 +For example, if you specify:
 +
 +@example
 +%define api.namespace "foo::bar"
 +@end example
 +
 +Bison uses @code{foo::bar} verbatim in references such as:
 +
 +@example
 +foo::bar::parser::semantic_type
 +@end example
 +
 +However, to open a namespace, Bison removes any leading @code{::} and then
 +splits on any remaining occurrences:
 +
 +@example
 +namespace foo @{ namespace bar @{
 +  class position;
 +  class location;
 +@} @}
 +@end example
 +
 +@item Accepted Values:
 +Any absolute or relative C++ namespace reference without a trailing
 +@code{"::"}.  For example, @code{"foo"} or @code{"::foo::bar"}.
 +
 +@item Default Value:
 +The value specified by @code{%name-prefix}, which defaults to @code{yy}.
 +This usage of @code{%name-prefix} is for backward compatibility and can
 +be confusing since @code{%name-prefix} also specifies the textual prefix
 +for the lexical analyzer function.  Thus, if you specify
 +@code{%name-prefix}, it is best to also specify @samp{%define
 +api.namespace} so that @code{%name-prefix} @emph{only} affects the
 +lexical analyzer function.  For example, if you specify:
 +
 +@example
 +%define api.namespace "foo"
 +%name-prefix "bar::"
 +@end example
 +
 +The parser namespace is @code{foo} and @code{yylex} is referenced as
 +@code{bar::lex}.
 +@end itemize
 +@c namespace
 +
+ @c ================================================== api.location.type
+ @item @code{api.location.type}
+ @findex %define api.location.type
+ @itemize @bullet
+ @item Language(s): C++
+ @item Purpose: Define the location type.
+ @xref{User Defined Location Type}.
+ @item Accepted Values: String
+ @item Default Value: none
+ @item History: introduced in Bison 2.7
+ @end itemize
  
  @c ================================================== api.prefix
 -@item @code{api.prefix}
 +@item api.prefix
  @findex %define api.prefix
  
  @itemize @bullet
@@@ -9564,8 -9228,9 +9581,10 @@@ in the following files
  @table @file
  @item position.hh
  @itemx location.hh
- The definition of the classes @code{position} and @code{location},
- used for location tracking when enabled.  @xref{C++ Location Values}.
+ The definition of the classes @code{position} and @code{location}, used for
 -location tracking.  These files are not generated if the @code{%define}
 -variable @code{api.location.type} is defined.  @xref{C++ Location Values}.
++location tracking when enabled.  These files are not generated if the
++@code{%define} variable @code{api.location.type} is defined.  @xref{C++
++Location Values}.
  
  @item stack.hh
  An auxiliary class @code{stack} used by the parser.
@@@ -9734,8 -9299,9 +9756,9 @@@ In this section @code{uint} is an abbre
  genuine code only the latter is used.
  
  @menu
 -* C++ position::                One point in the source file
 -* C++ location::                Two points in the source file
 +* C++ position::         One point in the source file
 +* C++ location::         Two points in the source file
+ * User Defined Location Type::  Required interface for locations
  @end menu
  
  @node C++ position
@@@ -398,8 -410,8 +398,9 @@@ muscle_percent_variable_update (char co
    const conversion_type conversion[] =
      {
        { "api.push_pull", "api.push-pull", },
+       { "location_type", "api.location.type", },
        { "lr.keep_unreachable_states", "lr.keep-unreachable-states", },
 +      { "namespace", "api.namespace", },
      };
    char const *res = variable;
    int i;
@@@ -420,19 -429,13 +421,13 @@@ muscle_percent_define_insert (char cons
                                char const *value,
                                muscle_percent_define_how how)
  {
-   char const *name;
-   char const *loc_name;
-   char const *syncline_name;
-   char const *how_name;
-   /* Permit certain names with underscores for backward compatibility.  */
-   variable = muscle_percent_variable_update (variable, variable_loc);
-   name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
-   loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
-   syncline_name =
+   /* Backward compatibility.  */
 -  char const *variable = muscle_percent_variable_update (var);
++  char const *variable = muscle_percent_variable_update (var, variable_loc);
+   char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
+   char const *loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
+   char const *syncline_name =
      UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
-   how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")");
+   char const *how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")");
  
    /* Command-line options are processed before the grammar file.  */
    if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
Simple merge
diff --cc src/system.h
     runs afoul of pre-C99 compilers that have <inttypes.h> or
     <stdint.h>, which are included below if available.  It also runs
     afoul of pre-C99 compilers that define these macros in <limits.h>.  */
 -# if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901
 -#  undef INT8_MIN
 -#  undef INT16_MIN
 -#  undef INT32_MIN
 -#  undef INT8_MAX
 -#  undef INT16_MAX
 -#  undef UINT8_MAX
 -#  undef INT32_MAX
 -#  undef UINT16_MAX
 -#  undef UINT32_MAX
 -# endif
 +#if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901
 +# undef INT8_MIN
 +# undef INT16_MIN
 +# undef INT32_MIN
 +# undef INT8_MAX
 +# undef INT16_MAX
 +# undef UINT8_MAX
 +# undef INT32_MAX
 +# undef UINT16_MAX
 +# undef UINT32_MAX
 +#endif
 +
 +#include <limits.h>
 +#include <stddef.h>
 +#include <stdlib.h>
 +#include <string.h>
 +
 +#define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
 +#define STREQ(L, R)  (strcmp(L, R) == 0)
 +#define STRNEQ(L, R) (!STREQ(L, R))
  
 -# include <limits.h>
 -# include <stddef.h>
 -# include <stdlib.h>
 -# include <string.h>
 -# include <unistd.h>
 -# include <inttypes.h>
 +/* Just like strncmp, but the second argument must be a literal string
 +   and you don't specify the length.  */
 +#define STRNCMP_LIT(S, Literal)                         \
 +  strncmp (S, "" Literal "", sizeof (Literal) - 1)
 +
 +/* Whether Literal is a prefix of S.  */
 +#define STRPREFIX_LIT(Literal, S)               \
 +  (STRNCMP_LIT (S, Literal) == 0)
 +
 +#include <unistd.h>
 +#include <inttypes.h>
  
 -# ifndef UINTPTR_MAX
+ #define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
+ #define STREQ(L, R)  (strcmp(L, R) == 0)
+ #define STRNEQ(L, R) (!STREQ(L, R))
 +#ifndef UINTPTR_MAX
  /* This isn't perfect, but it's good enough for Bison, which needs
     only to hash pointers.  */
  typedef size_t uintptr_t;
diff --cc tests/calc.at
@@@ -712,23 -710,18 +712,23 @@@ AT_CHECK_CALC([%skeleton "lalr1.cc" %de
  # Start a testing chunk which compiles `calc' grammar with
  # the C++ skeleton, and performs several tests over the parser.
  m4_define([AT_CHECK_CALC_LALR1_CC],
 -[AT_CHECK_CALC([%language "C++" %defines %locations] $@)])
 +[AT_CHECK_CALC([%language "C++"] $@)])
  
  AT_CHECK_CALC_LALR1_CC([])
 -AT_CHECK_CALC_LALR1_CC([%define api.location.type Span])
 -AT_CHECK_CALC_LALR1_CC([%error-verbose %name-prefix "calc" %verbose %yacc])
 -AT_CHECK_CALC_LALR1_CC([%error-verbose %define api.prefix "calc" %verbose %yacc])
 -AT_CHECK_CALC_LALR1_CC([%error-verbose %debug %name-prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR1_CC([%locations])
- AT_CHECK_CALC_LALR1_CC([%locations %define location_type Span])
++AT_CHECK_CALC_LALR1_CC([%locations %define api.location.type Span])
 +AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %name-prefix "calc" %verbose %yacc])
  
 -AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %define api.prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %define api.prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
  
 -AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
 -AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
 +AT_CHECK_CALC_LALR1_CC([%locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR1_CC([%locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %define api.tokens.prefix "TOK_" %verbose %yacc])
 +
 +AT_CHECK_CALC_LALR1_CC([%defines %locations %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
 +
 +AT_CHECK_CALC_LALR1_CC([%pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
 +AT_CHECK_CALC_LALR1_CC([%defines %locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
  
  
  
@@@ -746,19 -739,17 +746,19 @@@ AT_CHECK_CALC([%skeleton "glr.cc"]
  # Start a testing chunk which compiles `calc' grammar with
  # the GLR C++ skeleton, and performs several tests over the parser.
  m4_define([AT_CHECK_CALC_GLR_CC],
 -[AT_CHECK_CALC([%language "C++" %glr-parser %defines %locations] $@)])
 +[AT_CHECK_CALC([%language "C++" %glr-parser] $@)])
  
  AT_CHECK_CALC_GLR_CC([])
 -AT_CHECK_CALC_GLR_CC([%define api.location.type Span])
 -AT_CHECK_CALC_GLR_CC([%error-verbose %name-prefix "calc" %verbose %yacc])
 -AT_CHECK_CALC_GLR_CC([%error-verbose %define api.prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_GLR_CC([%locations])
- AT_CHECK_CALC_GLR_CC([%locations %define location_type Span])
++AT_CHECK_CALC_GLR_CC([%locations %define api.location.type Span])
 +AT_CHECK_CALC_GLR_CC([%defines %define parse.error verbose %name-prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_GLR_CC([%define parse.error verbose %define api.prefix "calc" %verbose %yacc])
  
  AT_CHECK_CALC_GLR_CC([%debug])
 -AT_CHECK_CALC_GLR_CC([%error-verbose %debug %name-prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_GLR_CC([%define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
  
 -AT_CHECK_CALC_GLR_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_GLR_CC([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_GLR_CC([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %define api.tokens.prefix "TOK_" %verbose %yacc])
  
 -AT_CHECK_CALC_GLR_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
 -AT_CHECK_CALC_GLR_CC([%pure-parser %error-verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
 +AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
 +AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
Simple merge
diff --cc tests/java.at
@@@ -751,7 -719,7 +751,7 @@@ AT_SETUP([Java stype, position_class an
  AT_CHECK_JAVA_MINIMAL([[
  %define stype "java.awt.Color"
  %type<java.awt.Color> start;
--%define location_type "MyLoc"
++%define api.location.type "MyLoc"
  %define position_type "MyPos"
  %code { class MyPos {} }]], [[$$ = $<java.awt.Color>1;]], [[MyPos]])
  AT_CHECK([[grep 'java.awt.Color' YYParser.java]], [0], [ignore])
@@@ -761,7 -729,7 +761,7 @@@ AT_CHECK([[$EGREP -v ' */?\*' YYParser.
  AT_CHECK_JAVA_MINIMAL_W_LEXER([[
  %define stype "java.awt.Color"
  %type<java.awt.Color> start;
--%define location_type "MyLoc"
++%define api.location.type "MyLoc"
  %define position_type "MyPos"
  %code { class MyPos {} }]], [], [[return EOF;]], [],
  [[$$ = $<java.awt.Color>1;]],
diff --cc tests/local.at
Simple merge