On Sat, 29 Sep 2007, Sebastian Pipping wrote: > (2) Nested namespaces do not work: > %prefix=abc::def should give > > namespace abc { > namespace def { > .. > } > } > > instead of > > namespace abc::def { > .. > } > > I guess?
I committed the following to implement this. Index: ChangeLog =================================================================== RCS file: /sources/bison/bison/ChangeLog,v retrieving revision 1.1733 diff -p -u -r1.1733 ChangeLog --- ChangeLog 8 Oct 2007 04:00:13 -0000 1.1733 +++ ChangeLog 8 Oct 2007 09:25:42 -0000 @@ -1,5 +1,30 @@ 2007-10-08 Joel E. Denny <[EMAIL PROTECTED]> + 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 <[EMAIL PROTECTED]> + Add syncline support and location accessor to internal %define interfaces. * data/bison.m4 (b4_percent_define_get_loc): New. Index: data/c++.m4 =================================================================== RCS file: /sources/bison/bison/data/c++.m4,v retrieving revision 1.16 diff -p -u -r1.16 c++.m4 --- data/c++.m4 15 Aug 2007 20:21:22 -0000 1.16 +++ data/c++.m4 8 Oct 2007 09:25:42 -0000 @@ -35,6 +35,51 @@ b4_percent_define_default([[define_locat [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) # ----------------------------------------------------- # Output the definition of the tokens as enums. Index: data/glr.cc =================================================================== RCS file: /sources/bison/bison/data/glr.cc,v retrieving revision 1.40 diff -p -u -r1.40 glr.cc --- data/glr.cc 15 Aug 2007 20:21:22 -0000 1.40 +++ data/glr.cc 8 Oct 2007 09:25:42 -0000 @@ -58,8 +58,6 @@ m4_include(b4_pkgdatadir/[location.cc]) m4_define([b4_parser_class_name], [b4_percent_define_get([[parser_class_name]])]) -m4_define([b4_namespace], - [b4_percent_define_get([[namespace]])]) # Save the parse parameters. m4_define([b4_parse_param_orig], m4_defn([b4_parse_param])) @@ -79,9 +77,9 @@ m4_define([b4_yy_symbol_print_generate], [static void], [[FILE *], []], [[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]], - [[const b4_namespace::b4_parser_class_name::location_type *yylocationp], + [[const b4_namespace_ref::b4_parser_class_name::location_type *yylocationp], [yylocationp]], b4_parse_param)[ { @@ -97,7 +95,7 @@ m4_append([b4_post_prologue], b4_c_ansi_function_decl([yyerror], [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, [[const char* msg], [msg]])]) @@ -111,7 +109,7 @@ m4_append([b4_epilogue], ]b4_c_ansi_function_def([yyerror], [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, [[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. m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl [ /// Build a parser object. @@ -203,7 +200,7 @@ m4_pushdef([b4_parse_param], m4_defn([b4 #endif ]m4_popdef([b4_parse_param])dnl -[} // namespace ]b4_namespace[ +b4_namespace_close[ ]]) @@ -211,10 +208,10 @@ m4_pushdef([b4_parse_param], m4_defn([b4 # Let glr.c believe that the user arguments include the parser itself. m4_ifset([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_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_popdef([b4_parse_param]) @@ -237,11 +234,10 @@ b4_copyright([Skeleton interface for Bis /* Using locations. */ #define YYLSP_NEEDED ]b4_locations_flag[ -namespace ]b4_namespace[ -{ +]b4_namespace_open[ class position; class location; -} +]b4_namespace_close[ #include "location.hh" @@ -269,8 +265,7 @@ namespace ]b4_namespace[ while (/*CONSTCOND*/ 0) #endif -namespace ]b4_namespace[ -{ +]b4_namespace_open[ /// A Bison parser. class ]b4_parser_class_name[ { @@ -368,13 +363,13 @@ b4_percent_define_flag_if([[global_token [b4_token_defines(b4_tokens)]) [ #ifndef YYSTYPE -# define YYSTYPE ]b4_namespace[::]b4_parser_class_name[::semantic_type +# define YYSTYPE ]b4_namespace_ref[::]b4_parser_class_name[::semantic_type #endif #ifndef YYLTYPE -# define YYLTYPE ]b4_namespace[::]b4_parser_class_name[::location_type +# define YYLTYPE ]b4_namespace_ref[::]b4_parser_class_name[::location_type #endif -} +]b4_namespace_close[ ]b4_percent_code_get([[provides]])[]dnl Index: data/lalr1.cc =================================================================== RCS file: /sources/bison/bison/data/lalr1.cc,v retrieving revision 1.158 diff -p -u -r1.158 lalr1.cc --- data/lalr1.cc 15 Aug 2007 20:21:22 -0000 1.158 +++ data/lalr1.cc 8 Oct 2007 09:25:42 -0000 @@ -20,8 +20,6 @@ m4_include(b4_pkgdatadir/[c++.m4]) m4_define([b4_parser_class_name], [b4_percent_define_get([[parser_class_name]])]) -m4_define([b4_namespace], - [b4_percent_define_get([[namespace]])]) # The header is mandatory. b4_defines_if([], @@ -51,11 +49,10 @@ dnl FIXME: This is wrong, we want comput #include <iostream> #include "stack.hh" -namespace ]b4_namespace[ -{ +]b4_namespace_open[ class position; class location; -} +]b4_namespace_close[ #include "location.hh" @@ -96,8 +93,7 @@ do { \ } while (false) #endif -namespace ]b4_namespace[ -{ +]b4_namespace_open[ /// A Bison parser. class ]b4_parser_class_name[ @@ -286,14 +282,14 @@ b4_error_verbose_if([, int tok])[); static const token_number_type yyundef_token_; ]b4_parse_param_vars[ }; -} +]b4_namespace_close[ ]b4_percent_define_flag_if([[global_tokens_and_yystype]], [b4_token_defines(b4_tokens) #ifndef YYSTYPE /* 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 ]) b4_percent_code_get([[provides]])[]dnl @@ -375,8 +371,7 @@ do { \ #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab -namespace ]b4_namespace[ -{ +]b4_namespace_open[ #if YYERROR_VERBOSE /* 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 ]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 dnl @@ -1062,8 +1057,7 @@ b4_copyright([Stack handling for Bison p #include <deque> -namespace ]b4_namespace[ -{ +]b4_namespace_open[ template <class T, class S = std::deque<T> > class stack { @@ -1149,7 +1143,7 @@ namespace ]b4_namespace[ const S& stack_; unsigned int range_; }; -} +]b4_namespace_close[ #endif // not BISON_STACK_HH] m4_divert_pop(0) Index: data/location.cc =================================================================== RCS file: /sources/bison/bison/data/location.cc,v retrieving revision 1.19 diff -p -u -r1.19 location.cc --- data/location.cc 15 Aug 2007 20:21:23 -0000 1.19 +++ data/location.cc 8 Oct 2007 09:25:42 -0000 @@ -25,7 +25,7 @@ b4_copyright([Positions for Bison parser /** ** \file position.hh - ** Define the ]b4_percent_define_get([[namespace]])[::position class. + ** Define the ]b4_namespace_ref[::position class. */ #ifndef BISON_POSITION_HH @@ -35,8 +35,7 @@ b4_copyright([Positions for Bison parser # include <string> # include <algorithm> -namespace ]b4_percent_define_get([[namespace]])[ -{ +]b4_namespace_open[ /// Abstract a position. class position { @@ -142,7 +141,7 @@ namespace ]b4_percent_define_get([[names return ostr << pos.line << '.' << pos.column; } -} +]b4_namespace_close[ #endif // not BISON_POSITION_HH] @output(b4_dir_prefix[]location.hh@) b4_copyright([Locations for Bison parsers in C++], @@ -150,7 +149,7 @@ b4_copyright([Locations for Bison parser /** ** \file location.hh - ** Define the ]b4_percent_define_get([[namespace]])[::location class. + ** Define the ]b4_namespace_ref[::location class. */ #ifndef BISON_LOCATION_HH @@ -160,8 +159,7 @@ b4_copyright([Locations for Bison parser # include <string> # include "position.hh" -namespace ]b4_percent_define_get([[namespace]])[ -{ +]b4_namespace_open[ /// Abstract a location. class location @@ -270,7 +268,7 @@ namespace ]b4_percent_define_get([[names return ostr; } -} +]b4_namespace_close[ #endif // not BISON_LOCATION_HH] m4_divert_pop(0) Index: doc/bison.texinfo =================================================================== RCS file: /sources/bison/bison/doc/bison.texinfo,v retrieving revision 1.237 diff -p -u -r1.237 bison.texinfo --- doc/bison.texinfo 25 Sep 2007 05:47:26 -0000 1.237 +++ doc/bison.texinfo 8 Oct 2007 09:25:46 -0000 @@ -4726,8 +4726,8 @@ where Bison should generate it. Not all values of @var{qualifier} are available for all target languages: @itemize @bullet [EMAIL PROTECTED] %code requires @item requires [EMAIL PROTECTED] %code requires @itemize @bullet @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 target language and/or parser skeleton. @end enumerate [EMAIL PROTECTED] deffn [EMAIL PROTECTED] {Directive} %define push_pull "@var{value}" -Bison declaration to request a @code{"pull"} parser, a @code{"push"} parser, or [EMAIL PROTECTED]"both"}. -The default @code{"@var{value}"} is @code{"pull"}. -This directive is currently only available for LALR(1) parsers in C. +Some of the accepted @var{variable}s are: + [EMAIL PROTECTED] @bullet [EMAIL PROTECTED] push_pull [EMAIL PROTECTED] %define push_pull + [EMAIL PROTECTED] @bullet [EMAIL PROTECTED] Language(s): C (LALR(1) only) + [EMAIL PROTECTED] Purpose: Requests a pull parser, a push parser, or both. @xref{Push Decl, ,A Push Parser}. + [EMAIL PROTECTED] Accepted Values: @code{"pull"}, @code{"push"}, @code{"both"} + [EMAIL PROTECTED] Default Value: @code{"pull"} [EMAIL PROTECTED] itemize + [EMAIL PROTECTED] namespace [EMAIL PROTECTED] %define namespace + [EMAIL PROTECTED] [EMAIL PROTECTED] Languages(s): C++ + [EMAIL PROTECTED] Purpose: Specifies the namespace for the parser class. +For example, if you specify: + [EMAIL PROTECTED] +%define namespace "foo::bar" [EMAIL PROTECTED] smallexample + +Bison uses @code{foo::bar} verbatim in references such as: + [EMAIL PROTECTED] +foo::bar::parser::semantic_type [EMAIL PROTECTED] smallexample + +However, to open a namespace, Bison removes any leading @code{::} and then +splits on any remaining occurrences: + [EMAIL PROTECTED] +namespace foo @{ namespace bar @{ + class position; + class location; [EMAIL PROTECTED] @} [EMAIL PROTECTED] smallexample + [EMAIL PROTECTED] Accepted Values: Any absolute or relative C++ namespace reference without +a trailing @code{"::"}. +For example, @code{"foo"} or @code{"::foo::bar"}. + [EMAIL PROTECTED] 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 [EMAIL PROTECTED] namespace} so that @code{%name-prefix} @emph{only} affects the +lexical analyzer function. +For example, if you specify: + [EMAIL PROTECTED] +%define namespace "foo" +%name-prefix "bar::" [EMAIL PROTECTED] smallexample + +The parser namespace is @code{foo} and @code{yylex} is referenced as [EMAIL PROTECTED]::lex}. [EMAIL PROTECTED] itemize [EMAIL PROTECTED] itemize + @end deffn @deffn {Directive} %defines @@ -4921,9 +4984,9 @@ is @code{yyparse}, @code{yylex}, @code{y @code{yypush_parse}, @code{yypull_parse}, @code{yypstate}, @code{yypstate_new} and @code{yypstate_delete} will 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, -it is only the surrounding namespace which is named @var{prefix} instead -of @samp{yy}. +names become @code{c_parse}, @code{c_lex}, and so on. +For C++ parsers, see the @code{%define namespace} documentation in this +section. @xref{Multiple Parsers, ,Multiple Parsers in the Same Program}. @end deffn @@ -7812,10 +7875,12 @@ The C++ @acronym{LALR}(1) parser is sele @option{--language=c++}. @xref{Decl Summary}. -When run, @command{bison} will create several -entities in the @samp{yy} namespace. Use the @samp{%name-prefix} -directive to change the namespace name, see @ref{Decl Summary}. The -various classes are generated in the following files: +When run, @command{bison} will create several entities in the @samp{yy} +namespace. [EMAIL PROTECTED] %define namespace +Use the @samp{%define namespace} directive to change the namespace name, see [EMAIL PROTECTED] Summary}. +The various classes are generated in the following files: @table @file @item position.hh @@ -9329,12 +9394,6 @@ Define a variable to adjust Bison's beha @xref{Decl Summary,,%define}. @end deffn [EMAIL PROTECTED] {Directive} %define push_pull "@var{value}" -Bison declaration to request a @code{"pull"} parser, a @code{"push"} parser, or [EMAIL PROTECTED]"both"}. [EMAIL PROTECTED] Summary,,%define push_pull}. [EMAIL PROTECTED] deffn - @deffn {Directive} %defines Bison declaration to create a header file meant for the scanner. @xref{Decl Summary}. Index: tests/c++.at =================================================================== RCS file: /sources/bison/bison/tests/c++.at,v retrieving revision 1.4 diff -p -u -r1.4 c++.at --- tests/c++.at 15 Aug 2007 20:21:32 -0000 1.4 +++ tests/c++.at 8 Oct 2007 09:25:46 -0000 @@ -99,3 +99,84 @@ m4_popdef([AT_DOXYGEN_PRIVATE]) AT_CHECK_DOXYGEN([Public]) 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 Index: tests/input.at =================================================================== RCS file: /sources/bison/bison/tests/input.at,v retrieving revision 1.81 diff -p -u -r1.81 input.at --- tests/input.at 25 Sep 2007 05:47:27 -0000 1.81 +++ tests/input.at 8 Oct 2007 09:25:47 -0000 @@ -858,3 +858,52 @@ AT_CHECK([[bison input.y]], [1], [], ]]) 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 _______________________________________________ help-bison@gnu.org http://lists.gnu.org/mailman/listinfo/help-bison