mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-19 01:03:04 +00:00
Improve C++ namespace support. Discussed starting at
<http://lists.gnu.org/archive/html/help-bison/2007-09/msg00016.html>. * data/c++.m4: (b4_namespace_ref, b4_namespace_open, b4_namespace_close): New macros that interpret the %define variable "namespace" so its value can contain "::" to indicate nested namespaces. * data/glr.cc (b4_namespace): Don't define, and replace all uses with the above macros. * data/lalr1.cc (b4_namespace): Likewise. * data/location.cc (b4_namespace): Likewise. * doc/bison.texinfo (Decl Summary): Move `%define push_pull' entry inside a new table in the general %define entry. Document `%define namespace' there as well. Point the %name-prefix entry to it since it explains it more completely in the case of C++. (C++ Bison Interface): Mention `%define namespace' instead of %name-prefix. (Table of Symbols): Remove the `%define push_pull' entry. The %define entry suffices. * tests/c++.at (Relative namespace references): New test case. (Absolute namespace references): New test case. (Syntactically invalid namespace references): New test case. * tests/input.at (C++ namespace reference errors): New test case.
This commit is contained in:
25
ChangeLog
25
ChangeLog
@@ -1,3 +1,28 @@
|
|||||||
|
2007-10-08 Joel E. Denny <jdenny@ces.clemson.edu>
|
||||||
|
|
||||||
|
Improve C++ namespace support. Discussed starting at
|
||||||
|
<http://lists.gnu.org/archive/html/help-bison/2007-09/msg00016.html>.
|
||||||
|
* data/c++.m4: (b4_namespace_ref, b4_namespace_open,
|
||||||
|
b4_namespace_close): New macros that interpret the %define variable
|
||||||
|
"namespace" so its value can contain "::" to indicate nested
|
||||||
|
namespaces.
|
||||||
|
* data/glr.cc (b4_namespace): Don't define, and replace all uses with
|
||||||
|
the above macros.
|
||||||
|
* data/lalr1.cc (b4_namespace): Likewise.
|
||||||
|
* data/location.cc (b4_namespace): Likewise.
|
||||||
|
* doc/bison.texinfo (Decl Summary): Move `%define push_pull' entry
|
||||||
|
inside a new table in the general %define entry. Document `%define
|
||||||
|
namespace' there as well. Point the %name-prefix entry to it since it
|
||||||
|
explains it more completely in the case of C++.
|
||||||
|
(C++ Bison Interface): Mention `%define namespace' instead of
|
||||||
|
%name-prefix.
|
||||||
|
(Table of Symbols): Remove the `%define push_pull' entry. The %define
|
||||||
|
entry suffices.
|
||||||
|
* tests/c++.at (Relative namespace references): New test case.
|
||||||
|
(Absolute namespace references): New test case.
|
||||||
|
(Syntactically invalid namespace references): New test case.
|
||||||
|
* tests/input.at (C++ namespace reference errors): New test case.
|
||||||
|
|
||||||
2007-10-08 Joel E. Denny <jdenny@ces.clemson.edu>
|
2007-10-08 Joel E. Denny <jdenny@ces.clemson.edu>
|
||||||
|
|
||||||
Add syncline support and location accessor to internal %define
|
Add syncline support and location accessor to internal %define
|
||||||
|
|||||||
45
data/c++.m4
45
data/c++.m4
@@ -35,6 +35,51 @@ b4_percent_define_default([[define_location_comparison]],
|
|||||||
[std::string], [[true]], [[false]])])
|
[std::string], [[true]], [[false]])])
|
||||||
|
|
||||||
|
|
||||||
|
## ----------- ##
|
||||||
|
## Namespace. ##
|
||||||
|
## ----------- ##
|
||||||
|
|
||||||
|
m4_define([b4_namespace_ref], [b4_percent_define_get([[namespace]])])
|
||||||
|
|
||||||
|
# Don't permit an empty b4_namespace_ref. Any `::parser::foo' appended to it
|
||||||
|
# would compile as an absolute reference with `parser' in the global namespace.
|
||||||
|
# b4_namespace_open would open an anonymous namespace and thus establish
|
||||||
|
# internal linkage. This would compile. However, it's cryptic, and internal
|
||||||
|
# linkage for the parser would be specified in all translation units that
|
||||||
|
# include the header, which is always generated. If we ever need to permit
|
||||||
|
# internal linkage somehow, surely we can find a cleaner approach.
|
||||||
|
m4_if(m4_bregexp(b4_namespace_ref, [^[ ]*$]), [-1], [],
|
||||||
|
[b4_complain_at(b4_percent_define_get_loc([[namespace]]),
|
||||||
|
[[namespace reference is empty]])])
|
||||||
|
|
||||||
|
# Instead of assuming the C++ compiler will do it, Bison should reject any
|
||||||
|
# invalid b4_namepsace_ref that would be converted to a valid
|
||||||
|
# b4_namespace_open. The problem is that Bison doesn't always output
|
||||||
|
# b4_namespace_ref to uncommented code but should reserve the ability to do so
|
||||||
|
# in future releases without risking breaking any existing user grammars.
|
||||||
|
# Specifically, don't allow empty names as b4_namespace_open would just convert
|
||||||
|
# those into anonymous namespaces, and that might tempt some users.
|
||||||
|
m4_if(m4_bregexp(b4_namespace_ref, [::[ ]*::]), [-1], [],
|
||||||
|
[b4_complain_at(b4_percent_define_get_loc([[namespace]]),
|
||||||
|
[[namespace reference has consecutive "::"]])])
|
||||||
|
m4_if(m4_bregexp(b4_namespace_ref, [::[ ]*$]), [-1], [],
|
||||||
|
[b4_complain_at(b4_percent_define_get_loc([[namespace]]),
|
||||||
|
[[namespace reference has a trailing "::"]])])
|
||||||
|
|
||||||
|
m4_define([b4_namespace_open],
|
||||||
|
[b4_user_code([b4_percent_define_get_syncline([[namespace]])
|
||||||
|
[namespace ]m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref),
|
||||||
|
[^\(.\)[ ]*::], [\1])),
|
||||||
|
[::], [ { namespace ])[ {]])])
|
||||||
|
|
||||||
|
m4_define([b4_namespace_close],
|
||||||
|
[b4_user_code([b4_percent_define_get_syncline([[namespace]])
|
||||||
|
m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref),
|
||||||
|
[^\(.\)[ ]*\(::\)?\([^][:]\|:[^][:]\)*],
|
||||||
|
[\1])),
|
||||||
|
[::\([^][:]\|:[^][:]\)*], [} ])[} // ]b4_namespace_ref])])
|
||||||
|
|
||||||
|
|
||||||
# b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
|
# b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
|
||||||
# -----------------------------------------------------
|
# -----------------------------------------------------
|
||||||
# Output the definition of the tokens as enums.
|
# Output the definition of the tokens as enums.
|
||||||
|
|||||||
33
data/glr.cc
33
data/glr.cc
@@ -58,8 +58,6 @@ m4_include(b4_pkgdatadir/[location.cc])
|
|||||||
|
|
||||||
m4_define([b4_parser_class_name],
|
m4_define([b4_parser_class_name],
|
||||||
[b4_percent_define_get([[parser_class_name]])])
|
[b4_percent_define_get([[parser_class_name]])])
|
||||||
m4_define([b4_namespace],
|
|
||||||
[b4_percent_define_get([[namespace]])])
|
|
||||||
|
|
||||||
# Save the parse parameters.
|
# Save the parse parameters.
|
||||||
m4_define([b4_parse_param_orig], m4_defn([b4_parse_param]))
|
m4_define([b4_parse_param_orig], m4_defn([b4_parse_param]))
|
||||||
@@ -79,9 +77,9 @@ m4_define([b4_yy_symbol_print_generate],
|
|||||||
[static void],
|
[static void],
|
||||||
[[FILE *], []],
|
[[FILE *], []],
|
||||||
[[int yytype], [yytype]],
|
[[int yytype], [yytype]],
|
||||||
[[const b4_namespace::b4_parser_class_name::semantic_type *yyvaluep],
|
[[const b4_namespace_ref::b4_parser_class_name::semantic_type *yyvaluep],
|
||||||
[yyvaluep]],
|
[yyvaluep]],
|
||||||
[[const b4_namespace::b4_parser_class_name::location_type *yylocationp],
|
[[const b4_namespace_ref::b4_parser_class_name::location_type *yylocationp],
|
||||||
[yylocationp]],
|
[yylocationp]],
|
||||||
b4_parse_param)[
|
b4_parse_param)[
|
||||||
{
|
{
|
||||||
@@ -97,7 +95,7 @@ m4_append([b4_post_prologue],
|
|||||||
|
|
||||||
b4_c_ansi_function_decl([yyerror],
|
b4_c_ansi_function_decl([yyerror],
|
||||||
[static void],
|
[static void],
|
||||||
[[b4_namespace::b4_parser_class_name::location_type *yylocationp], [yylocationp]],
|
[[b4_namespace_ref::b4_parser_class_name::location_type *yylocationp], [yylocationp]],
|
||||||
b4_parse_param,
|
b4_parse_param,
|
||||||
[[const char* msg], [msg]])])
|
[[const char* msg], [msg]])])
|
||||||
|
|
||||||
@@ -111,7 +109,7 @@ m4_append([b4_epilogue],
|
|||||||
|
|
||||||
]b4_c_ansi_function_def([yyerror],
|
]b4_c_ansi_function_def([yyerror],
|
||||||
[static void],
|
[static void],
|
||||||
[[b4_namespace::b4_parser_class_name::location_type *yylocationp], [yylocationp]],
|
[[b4_namespace_ref::b4_parser_class_name::location_type *yylocationp], [yylocationp]],
|
||||||
b4_parse_param,
|
b4_parse_param,
|
||||||
[[const char* msg], [msg]])[
|
[[const char* msg], [msg]])[
|
||||||
{
|
{
|
||||||
@@ -120,8 +118,7 @@ m4_append([b4_epilogue],
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace ]b4_namespace[
|
]b4_namespace_open[
|
||||||
{
|
|
||||||
]dnl In this section, the parse param are the original parse_params.
|
]dnl In this section, the parse param are the original parse_params.
|
||||||
m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
|
m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
|
||||||
[ /// Build a parser object.
|
[ /// Build a parser object.
|
||||||
@@ -203,7 +200,7 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
]m4_popdef([b4_parse_param])dnl
|
]m4_popdef([b4_parse_param])dnl
|
||||||
[} // namespace ]b4_namespace[
|
b4_namespace_close[
|
||||||
|
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -211,10 +208,10 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
|
|||||||
# Let glr.c believe that the user arguments include the parser itself.
|
# Let glr.c believe that the user arguments include the parser itself.
|
||||||
m4_ifset([b4_parse_param],
|
m4_ifset([b4_parse_param],
|
||||||
[m4_pushdef([b4_parse_param],
|
[m4_pushdef([b4_parse_param],
|
||||||
m4_dquote([[[b4_namespace::b4_parser_class_name& yyparser], [[yyparser]]],]
|
m4_dquote([[[b4_namespace_ref::b4_parser_class_name& yyparser], [[yyparser]]],]
|
||||||
m4_defn([b4_parse_param])))],
|
m4_defn([b4_parse_param])))],
|
||||||
[m4_pushdef([b4_parse_param],
|
[m4_pushdef([b4_parse_param],
|
||||||
[[[[b4_namespace::b4_parser_class_name& yyparser], [[yyparser]]]]])
|
[[[[b4_namespace_ref::b4_parser_class_name& yyparser], [[yyparser]]]]])
|
||||||
])
|
])
|
||||||
m4_include(b4_pkgdatadir/[glr.c])
|
m4_include(b4_pkgdatadir/[glr.c])
|
||||||
m4_popdef([b4_parse_param])
|
m4_popdef([b4_parse_param])
|
||||||
@@ -237,11 +234,10 @@ b4_copyright([Skeleton interface for Bison GLR parsers in C++],
|
|||||||
/* Using locations. */
|
/* Using locations. */
|
||||||
#define YYLSP_NEEDED ]b4_locations_flag[
|
#define YYLSP_NEEDED ]b4_locations_flag[
|
||||||
|
|
||||||
namespace ]b4_namespace[
|
]b4_namespace_open[
|
||||||
{
|
|
||||||
class position;
|
class position;
|
||||||
class location;
|
class location;
|
||||||
}
|
]b4_namespace_close[
|
||||||
|
|
||||||
#include "location.hh"
|
#include "location.hh"
|
||||||
|
|
||||||
@@ -269,8 +265,7 @@ namespace ]b4_namespace[
|
|||||||
while (/*CONSTCOND*/ 0)
|
while (/*CONSTCOND*/ 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ]b4_namespace[
|
]b4_namespace_open[
|
||||||
{
|
|
||||||
/// A Bison parser.
|
/// A Bison parser.
|
||||||
class ]b4_parser_class_name[
|
class ]b4_parser_class_name[
|
||||||
{
|
{
|
||||||
@@ -368,13 +363,13 @@ b4_percent_define_flag_if([[global_tokens_and_yystype]],
|
|||||||
[b4_token_defines(b4_tokens)])
|
[b4_token_defines(b4_tokens)])
|
||||||
[
|
[
|
||||||
#ifndef YYSTYPE
|
#ifndef YYSTYPE
|
||||||
# define YYSTYPE ]b4_namespace[::]b4_parser_class_name[::semantic_type
|
# define YYSTYPE ]b4_namespace_ref[::]b4_parser_class_name[::semantic_type
|
||||||
#endif
|
#endif
|
||||||
#ifndef YYLTYPE
|
#ifndef YYLTYPE
|
||||||
# define YYLTYPE ]b4_namespace[::]b4_parser_class_name[::location_type
|
# define YYLTYPE ]b4_namespace_ref[::]b4_parser_class_name[::location_type
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
]b4_namespace_close[
|
||||||
|
|
||||||
]b4_percent_code_get([[provides]])[]dnl
|
]b4_percent_code_get([[provides]])[]dnl
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ m4_include(b4_pkgdatadir/[c++.m4])
|
|||||||
|
|
||||||
m4_define([b4_parser_class_name],
|
m4_define([b4_parser_class_name],
|
||||||
[b4_percent_define_get([[parser_class_name]])])
|
[b4_percent_define_get([[parser_class_name]])])
|
||||||
m4_define([b4_namespace],
|
|
||||||
[b4_percent_define_get([[namespace]])])
|
|
||||||
|
|
||||||
# The header is mandatory.
|
# The header is mandatory.
|
||||||
b4_defines_if([],
|
b4_defines_if([],
|
||||||
@@ -51,11 +49,10 @@ dnl FIXME: This is wrong, we want computed header guards.
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "stack.hh"
|
#include "stack.hh"
|
||||||
|
|
||||||
namespace ]b4_namespace[
|
]b4_namespace_open[
|
||||||
{
|
|
||||||
class position;
|
class position;
|
||||||
class location;
|
class location;
|
||||||
}
|
]b4_namespace_close[
|
||||||
|
|
||||||
#include "location.hh"
|
#include "location.hh"
|
||||||
|
|
||||||
@@ -96,8 +93,7 @@ do { \
|
|||||||
} while (false)
|
} while (false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ]b4_namespace[
|
]b4_namespace_open[
|
||||||
{
|
|
||||||
|
|
||||||
/// A Bison parser.
|
/// A Bison parser.
|
||||||
class ]b4_parser_class_name[
|
class ]b4_parser_class_name[
|
||||||
@@ -286,14 +282,14 @@ b4_error_verbose_if([, int tok])[);
|
|||||||
static const token_number_type yyundef_token_;
|
static const token_number_type yyundef_token_;
|
||||||
]b4_parse_param_vars[
|
]b4_parse_param_vars[
|
||||||
};
|
};
|
||||||
}
|
]b4_namespace_close[
|
||||||
|
|
||||||
]b4_percent_define_flag_if([[global_tokens_and_yystype]],
|
]b4_percent_define_flag_if([[global_tokens_and_yystype]],
|
||||||
[b4_token_defines(b4_tokens)
|
[b4_token_defines(b4_tokens)
|
||||||
|
|
||||||
#ifndef YYSTYPE
|
#ifndef YYSTYPE
|
||||||
/* Redirection for backward compatibility. */
|
/* Redirection for backward compatibility. */
|
||||||
# define YYSTYPE b4_namespace::b4_parser_class_name::semantic_type
|
# define YYSTYPE b4_namespace_ref::b4_parser_class_name::semantic_type
|
||||||
#endif
|
#endif
|
||||||
])
|
])
|
||||||
b4_percent_code_get([[provides]])[]dnl
|
b4_percent_code_get([[provides]])[]dnl
|
||||||
@@ -375,8 +371,7 @@ do { \
|
|||||||
#define YYABORT goto yyabortlab
|
#define YYABORT goto yyabortlab
|
||||||
#define YYERROR goto yyerrorlab
|
#define YYERROR goto yyerrorlab
|
||||||
|
|
||||||
namespace ]b4_namespace[
|
]b4_namespace_open[
|
||||||
{
|
|
||||||
#if YYERROR_VERBOSE
|
#if YYERROR_VERBOSE
|
||||||
|
|
||||||
/* Return YYSTR after stripping away unnecessary quotes and
|
/* Return YYSTR after stripping away unnecessary quotes and
|
||||||
@@ -1049,7 +1044,7 @@ b4_error_verbose_if([, int tok])[)
|
|||||||
const unsigned int ]b4_parser_class_name[::yyuser_token_number_max_ = ]b4_user_token_number_max[;
|
const unsigned int ]b4_parser_class_name[::yyuser_token_number_max_ = ]b4_user_token_number_max[;
|
||||||
const ]b4_parser_class_name[::token_number_type ]b4_parser_class_name[::yyundef_token_ = ]b4_undef_token_number[;
|
const ]b4_parser_class_name[::token_number_type ]b4_parser_class_name[::yyundef_token_ = ]b4_undef_token_number[;
|
||||||
|
|
||||||
} // namespace ]b4_namespace[
|
]b4_namespace_close[
|
||||||
|
|
||||||
]b4_epilogue
|
]b4_epilogue
|
||||||
dnl
|
dnl
|
||||||
@@ -1062,8 +1057,7 @@ b4_copyright([Stack handling for Bison parsers in C++],
|
|||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
namespace ]b4_namespace[
|
]b4_namespace_open[
|
||||||
{
|
|
||||||
template <class T, class S = std::deque<T> >
|
template <class T, class S = std::deque<T> >
|
||||||
class stack
|
class stack
|
||||||
{
|
{
|
||||||
@@ -1149,7 +1143,7 @@ namespace ]b4_namespace[
|
|||||||
const S& stack_;
|
const S& stack_;
|
||||||
unsigned int range_;
|
unsigned int range_;
|
||||||
};
|
};
|
||||||
}
|
]b4_namespace_close[
|
||||||
|
|
||||||
#endif // not BISON_STACK_HH]
|
#endif // not BISON_STACK_HH]
|
||||||
m4_divert_pop(0)
|
m4_divert_pop(0)
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ b4_copyright([Positions for Bison parsers in C++],
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
** \file position.hh
|
** \file position.hh
|
||||||
** Define the ]b4_percent_define_get([[namespace]])[::position class.
|
** Define the ]b4_namespace_ref[::position class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BISON_POSITION_HH
|
#ifndef BISON_POSITION_HH
|
||||||
@@ -35,8 +35,7 @@ b4_copyright([Positions for Bison parsers in C++],
|
|||||||
# include <string>
|
# include <string>
|
||||||
# include <algorithm>
|
# include <algorithm>
|
||||||
|
|
||||||
namespace ]b4_percent_define_get([[namespace]])[
|
]b4_namespace_open[
|
||||||
{
|
|
||||||
/// Abstract a position.
|
/// Abstract a position.
|
||||||
class position
|
class position
|
||||||
{
|
{
|
||||||
@@ -142,7 +141,7 @@ namespace ]b4_percent_define_get([[namespace]])[
|
|||||||
return ostr << pos.line << '.' << pos.column;
|
return ostr << pos.line << '.' << pos.column;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
]b4_namespace_close[
|
||||||
#endif // not BISON_POSITION_HH]
|
#endif // not BISON_POSITION_HH]
|
||||||
@output(b4_dir_prefix[]location.hh@)
|
@output(b4_dir_prefix[]location.hh@)
|
||||||
b4_copyright([Locations for Bison parsers in C++],
|
b4_copyright([Locations for Bison parsers in C++],
|
||||||
@@ -150,7 +149,7 @@ b4_copyright([Locations for Bison parsers in C++],
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
** \file location.hh
|
** \file location.hh
|
||||||
** Define the ]b4_percent_define_get([[namespace]])[::location class.
|
** Define the ]b4_namespace_ref[::location class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BISON_LOCATION_HH
|
#ifndef BISON_LOCATION_HH
|
||||||
@@ -160,8 +159,7 @@ b4_copyright([Locations for Bison parsers in C++],
|
|||||||
# include <string>
|
# include <string>
|
||||||
# include "position.hh"
|
# include "position.hh"
|
||||||
|
|
||||||
namespace ]b4_percent_define_get([[namespace]])[
|
]b4_namespace_open[
|
||||||
{
|
|
||||||
|
|
||||||
/// Abstract a location.
|
/// Abstract a location.
|
||||||
class location
|
class location
|
||||||
@@ -270,7 +268,7 @@ namespace ]b4_percent_define_get([[namespace]])[
|
|||||||
return ostr;
|
return ostr;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
]b4_namespace_close[
|
||||||
|
|
||||||
#endif // not BISON_LOCATION_HH]
|
#endif // not BISON_LOCATION_HH]
|
||||||
m4_divert_pop(0)
|
m4_divert_pop(0)
|
||||||
|
|||||||
@@ -4726,8 +4726,8 @@ where Bison should generate it.
|
|||||||
Not all values of @var{qualifier} are available for all target languages:
|
Not all values of @var{qualifier} are available for all target languages:
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@findex %code requires
|
|
||||||
@item requires
|
@item requires
|
||||||
|
@findex %code requires
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item Language(s): C, C++
|
@item Language(s): C, C++
|
||||||
@@ -4833,14 +4833,77 @@ This is equivalent to @code{"true"}.
|
|||||||
In this case, Bison selects a default value, which may depend on the selected
|
In this case, Bison selects a default value, which may depend on the selected
|
||||||
target language and/or parser skeleton.
|
target language and/or parser skeleton.
|
||||||
@end enumerate
|
@end enumerate
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@deffn {Directive} %define push_pull "@var{value}"
|
Some of the accepted @var{variable}s are:
|
||||||
Bison declaration to request a @code{"pull"} parser, a @code{"push"} parser, or
|
|
||||||
@code{"both"}.
|
@itemize @bullet
|
||||||
The default @code{"@var{value}"} is @code{"pull"}.
|
@item push_pull
|
||||||
This directive is currently only available for LALR(1) parsers in C.
|
@findex %define push_pull
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item Language(s): C (LALR(1) only)
|
||||||
|
|
||||||
|
@item Purpose: Requests a pull parser, a push parser, or both.
|
||||||
@xref{Push Decl, ,A Push Parser}.
|
@xref{Push Decl, ,A Push Parser}.
|
||||||
|
|
||||||
|
@item Accepted Values: @code{"pull"}, @code{"push"}, @code{"both"}
|
||||||
|
|
||||||
|
@item Default Value: @code{"pull"}
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@item namespace
|
||||||
|
@findex %define namespace
|
||||||
|
|
||||||
|
@itemize
|
||||||
|
@item Languages(s): C++
|
||||||
|
|
||||||
|
@item Purpose: Specifies the namespace for the parser class.
|
||||||
|
For example, if you specify:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
%define namespace "foo::bar"
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
Bison uses @code{foo::bar} verbatim in references such as:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
foo::bar::parser::semantic_type
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
However, to open a namespace, Bison removes any leading @code{::} and then
|
||||||
|
splits on any remaining occurrences:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
namespace foo @{ namespace bar @{
|
||||||
|
class position;
|
||||||
|
class location;
|
||||||
|
@} @}
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
@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
|
||||||
|
@code{%define namespace} so that @code{%name-prefix} @emph{only} affects the
|
||||||
|
lexical analyzer function.
|
||||||
|
For example, if you specify:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
%define namespace "foo"
|
||||||
|
%name-prefix "bar::"
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
The parser namespace is @code{foo} and @code{yylex} is referenced as
|
||||||
|
@code{bar::lex}.
|
||||||
|
@end itemize
|
||||||
|
@end itemize
|
||||||
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Directive} %defines
|
@deffn {Directive} %defines
|
||||||
@@ -4921,9 +4984,9 @@ is @code{yyparse}, @code{yylex}, @code{yyerror}, @code{yynerrs},
|
|||||||
@code{yypush_parse}, @code{yypull_parse}, @code{yypstate},
|
@code{yypush_parse}, @code{yypull_parse}, @code{yypstate},
|
||||||
@code{yypstate_new} and @code{yypstate_delete} will
|
@code{yypstate_new} and @code{yypstate_delete} will
|
||||||
also be renamed. For example, if you use @samp{%name-prefix "c_"}, the
|
also be renamed. For example, if you use @samp{%name-prefix "c_"}, the
|
||||||
names become @code{c_parse}, @code{c_lex}, and so on. In C++ parsers,
|
names become @code{c_parse}, @code{c_lex}, and so on.
|
||||||
it is only the surrounding namespace which is named @var{prefix} instead
|
For C++ parsers, see the @code{%define namespace} documentation in this
|
||||||
of @samp{yy}.
|
section.
|
||||||
@xref{Multiple Parsers, ,Multiple Parsers in the Same Program}.
|
@xref{Multiple Parsers, ,Multiple Parsers in the Same Program}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@@ -7812,10 +7875,12 @@ The C++ @acronym{LALR}(1) parser is selected using the language directive,
|
|||||||
@option{--language=c++}.
|
@option{--language=c++}.
|
||||||
@xref{Decl Summary}.
|
@xref{Decl Summary}.
|
||||||
|
|
||||||
When run, @command{bison} will create several
|
When run, @command{bison} will create several entities in the @samp{yy}
|
||||||
entities in the @samp{yy} namespace. Use the @samp{%name-prefix}
|
namespace.
|
||||||
directive to change the namespace name, see @ref{Decl Summary}. The
|
@findex %define namespace
|
||||||
various classes are generated in the following files:
|
Use the @samp{%define namespace} directive to change the namespace name, see
|
||||||
|
@ref{Decl Summary}.
|
||||||
|
The various classes are generated in the following files:
|
||||||
|
|
||||||
@table @file
|
@table @file
|
||||||
@item position.hh
|
@item position.hh
|
||||||
@@ -9329,12 +9394,6 @@ Define a variable to adjust Bison's behavior.
|
|||||||
@xref{Decl Summary,,%define}.
|
@xref{Decl Summary,,%define}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Directive} %define push_pull "@var{value}"
|
|
||||||
Bison declaration to request a @code{"pull"} parser, a @code{"push"} parser, or
|
|
||||||
@code{"both"}.
|
|
||||||
@xref{Decl Summary,,%define push_pull}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@deffn {Directive} %defines
|
@deffn {Directive} %defines
|
||||||
Bison declaration to create a header file meant for the scanner.
|
Bison declaration to create a header file meant for the scanner.
|
||||||
@xref{Decl Summary}.
|
@xref{Decl Summary}.
|
||||||
|
|||||||
83
tests/c++.at
83
tests/c++.at
@@ -1,5 +1,5 @@
|
|||||||
# Checking the output filenames. -*- Autotest -*-
|
# Checking the output filenames. -*- Autotest -*-
|
||||||
# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -99,3 +99,84 @@ m4_popdef([AT_DOXYGEN_PRIVATE])
|
|||||||
|
|
||||||
AT_CHECK_DOXYGEN([Public])
|
AT_CHECK_DOXYGEN([Public])
|
||||||
AT_CHECK_DOXYGEN([Private])
|
AT_CHECK_DOXYGEN([Private])
|
||||||
|
|
||||||
|
## ------------ ##
|
||||||
|
## Namespaces. ##
|
||||||
|
## ------------ ##
|
||||||
|
|
||||||
|
# AT_CHECK_NAMESPACE(NAMESPACE-DECL, [COMPILE-ERROR])
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# See if Bison can handle %define namespace "NAMESPACE-DECL". If COMPILE-ERROR
|
||||||
|
# is specified, then Bison should accept the input, but compilation will fail,
|
||||||
|
# so don't check compilation.
|
||||||
|
m4_define([AT_CHECK_NAMESPACE],
|
||||||
|
[
|
||||||
|
|
||||||
|
AT_DATA_GRAMMAR([[input.y]],
|
||||||
|
[[%language "C++"
|
||||||
|
%defines
|
||||||
|
%define namespace "]$1["
|
||||||
|
%union { int i; }
|
||||||
|
%define global_tokens_and_yystype
|
||||||
|
|
||||||
|
%code {
|
||||||
|
// YYSTYPE contains a namespace reference.
|
||||||
|
int yylex (YYSTYPE *lval) {
|
||||||
|
lval->i = 3;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
start: ;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
void
|
||||||
|
]$1[::parser::error (const ]$1[::parser::location_type &loc,
|
||||||
|
const std::string &msg)
|
||||||
|
{
|
||||||
|
std::cerr << "At " << loc << ": " << msg << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
]$1[::parser p;
|
||||||
|
return p.parse ();
|
||||||
|
}
|
||||||
|
]])
|
||||||
|
|
||||||
|
AT_CHECK([[bison -o input.cc input.y]])
|
||||||
|
|
||||||
|
m4_if([$#], [1],
|
||||||
|
[AT_COMPILE_CXX([[input]], [[input.cc]])
|
||||||
|
AT_PARSER_CHECK([[./input]])])
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
AT_SETUP([[Relative namespace references]])
|
||||||
|
AT_CHECK_NAMESPACE([[foo]])
|
||||||
|
AT_CHECK_NAMESPACE([[foo::bar]])
|
||||||
|
AT_CHECK_NAMESPACE([[foo::bar::baz]])
|
||||||
|
AT_CLEANUP
|
||||||
|
|
||||||
|
AT_SETUP([[Absolute namespace references]])
|
||||||
|
AT_CHECK_NAMESPACE([[::foo]])
|
||||||
|
AT_CHECK_NAMESPACE([[::foo::bar]])
|
||||||
|
AT_CHECK_NAMESPACE([[::foo::bar::baz]])
|
||||||
|
AT_CHECK_NAMESPACE([[ ::foo]])
|
||||||
|
AT_CHECK_NAMESPACE([[ ::foo::bar]])
|
||||||
|
AT_CHECK_NAMESPACE([[ ::foo::bar::baz]])
|
||||||
|
AT_CLEANUP
|
||||||
|
|
||||||
|
AT_SETUP([[Syntactically invalid namespace references]])
|
||||||
|
AT_CHECK_NAMESPACE([[:foo:bar]], [[-]])
|
||||||
|
AT_CHECK_NAMESPACE([[foo: :bar]], [[-]])
|
||||||
|
# This one is interesting because `[3]' is encoded as `@<:@3@:>@', which
|
||||||
|
# contains single occurrences of `:'.
|
||||||
|
AT_CHECK_NAMESPACE([[foo[3]::bar::baz]], [[-]])
|
||||||
|
AT_CHECK_NAMESPACE([[foo::bar,baz]], [[-]])
|
||||||
|
AT_CHECK_NAMESPACE([[foo::bar::(baz]], [[-]])
|
||||||
|
AT_CLEANUP
|
||||||
|
|||||||
@@ -858,3 +858,52 @@ AT_CHECK([[bison input.y]], [1], [],
|
|||||||
]])
|
]])
|
||||||
|
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
|
## -------------------------------- ##
|
||||||
|
## C++ namespace reference errors. ##
|
||||||
|
## -------------------------------- ##
|
||||||
|
|
||||||
|
AT_SETUP([[C++ namespace reference errors]])
|
||||||
|
|
||||||
|
# AT_CHECK_NAMESPACE_ERROR(NAMESPACE-DECL, ERROR, [ERROR], ...)
|
||||||
|
# -------------------------------------------------------------
|
||||||
|
# Make sure Bison reports all ERROR's for %define namespace "NAMESPACE-DECL".
|
||||||
|
m4_define([AT_CHECK_NAMESPACE_ERROR],
|
||||||
|
[
|
||||||
|
AT_DATA([[input.y]],
|
||||||
|
[[%language "C++"
|
||||||
|
%defines
|
||||||
|
%define namespace "]$1["
|
||||||
|
%%
|
||||||
|
start: ;
|
||||||
|
]])
|
||||||
|
|
||||||
|
AT_CHECK([[bison input.y]], [1], [],
|
||||||
|
[m4_foreach([b4_arg], m4_dquote(m4_shift($@)),
|
||||||
|
[[input.y:3.9-17: ]b4_arg[
|
||||||
|
]])])
|
||||||
|
])
|
||||||
|
|
||||||
|
AT_CHECK_NAMESPACE_ERROR([[]],
|
||||||
|
[[namespace reference is empty]])
|
||||||
|
AT_CHECK_NAMESPACE_ERROR([[ ]],
|
||||||
|
[[namespace reference is empty]])
|
||||||
|
AT_CHECK_NAMESPACE_ERROR([[foo::::bar]],
|
||||||
|
[[namespace reference has consecutive "::"]])
|
||||||
|
AT_CHECK_NAMESPACE_ERROR([[foo:: ::bar]],
|
||||||
|
[[namespace reference has consecutive "::"]])
|
||||||
|
AT_CHECK_NAMESPACE_ERROR([[::::bar]],
|
||||||
|
[[namespace reference has consecutive "::"]])
|
||||||
|
AT_CHECK_NAMESPACE_ERROR([[:: ::bar]],
|
||||||
|
[[namespace reference has consecutive "::"]])
|
||||||
|
AT_CHECK_NAMESPACE_ERROR([[foo::bar:: ::]],
|
||||||
|
[[namespace reference has consecutive "::"]],
|
||||||
|
[[namespace reference has a trailing "::"]])
|
||||||
|
AT_CHECK_NAMESPACE_ERROR([[foo::bar::]],
|
||||||
|
[[namespace reference has a trailing "::"]])
|
||||||
|
AT_CHECK_NAMESPACE_ERROR([[foo::bar:: ]],
|
||||||
|
[[namespace reference has a trailing "::"]])
|
||||||
|
AT_CHECK_NAMESPACE_ERROR([[::]],
|
||||||
|
[[namespace reference has a trailing "::"]])
|
||||||
|
|
||||||
|
AT_CLEANUP
|
||||||
|
|||||||
Reference in New Issue
Block a user