"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
# 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]]),
## 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])
# --------------------
# 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]])])
#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[
{
# %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]])])
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[
{
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
@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.
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
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;
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
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;
# 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}])
# 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}])
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])
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;]],