Merge remote-tracking branch 'origin/maint'

* origin/maint:
  tests: split a large test case into several smaller ones
  package: a bit of trouble shooting indications
  doc: liby's main arms the internationalization
  bison: avoid warnings from static code analysis
  c++: fix the use of destructors when variants are enabled
  style: tests: simplify the handling of some C++ tests
  c++: symbols can be empty, so use it
  c++: variants: don't leak the lookahead in error recovery
  c++: provide a means to clear symbols
  c++: clean up the handling of empty symbols
  c++: comment and style changes
  c++: variants: comparing addresses of typeid.name() is undefined
  c++: locations: complete the API and fix comments
  build: do not clean figure sources in make clean
This commit is contained in:
Akim Demaille
2015-01-13 14:43:02 +01:00
15 changed files with 270 additions and 152 deletions

14
NEWS
View File

@@ -4,19 +4,23 @@ GNU Bison NEWS
** Bug fixes ** Bug fixes
*** Named %union support *** C++ with Variants (lalr1.cc)
Problems with %destructor and '%define parse.assert' have been fixed.
*** Named %union support (yacc.c, glr.c)
Bison 3.0 introduced a regression on named %union such as Bison 3.0 introduced a regression on named %union such as
%union foo { int ival; }; %union foo { int ival; };
The possibility to use a name was introduced ``for Yacc compatibility''. The possibility to use a name was introduced "for Yacc compatibility".
It is however not required by POSIX Yacc, and its usefulness is not clear. It is however not required by POSIX Yacc, and its usefulness is not clear.
*** %define api.value.type union with %defines *** %define api.value.type union with %defines (yacc.c, glr.c)
The yacc.c and glr.c parsers were broken when %defines was used The C parsers were broken when %defines was used together with "%define
together with "%define api.value.type union". api.value.type union".
*** Redeclarations are reported in proper order *** Redeclarations are reported in proper order

View File

@@ -103,15 +103,17 @@ to perform the first checkout of the submodules, run
$ git submodule update --init $ git submodule update --init
Git submodule support is weak before versions 1.6 and later, you Git submodule support is weak before versions 1.6 and later, upgrade Git if
should probably upgrade Git if your version is older. your version is older.
The next step is to get other files needed to build, which are The next step is to get other files needed to build, which are
extracted from other source packages: extracted from other source packages:
$ ./bootstrap $ ./bootstrap
And there you are! Just If it fails with missing symbols (e.g., "error: possibly undefined macro:
AC_PROG_GNU_M4"), you are likely to have forgotten the submodule
initialization part. Otherwise, there you are! Just
$ ./configure $ ./configure
$ make $ make

6
THANKS
View File

@@ -12,6 +12,7 @@ Andreas Schwab schwab@suse.de
Andrew Suffield asuffield@users.sourceforge.net Andrew Suffield asuffield@users.sourceforge.net
Angelo Borsotti angelo.borsotti@gmail.com Angelo Borsotti angelo.borsotti@gmail.com
Anthony Heading ajrh@ajrh.net Anthony Heading ajrh@ajrh.net
Antonio Silva Correia amsilvacorreia@hotmail.com
Arnold Robbins arnold@skeeve.com Arnold Robbins arnold@skeeve.com
Art Haas ahaas@neosoft.com Art Haas ahaas@neosoft.com
Baron Schwartz baron@sequent.org Baron Schwartz baron@sequent.org
@@ -82,15 +83,19 @@ Martin Mokrejs mmokrejs@natur.cuni.cz
Martin Nylin martin.nylin@linuxmail.org Martin Nylin martin.nylin@linuxmail.org
Matt Kraai kraai@alumni.cmu.edu Matt Kraai kraai@alumni.cmu.edu
Matt Rosing rosing@peakfive.com Matt Rosing rosing@peakfive.com
Michael Catanzaro mcatanzaro@gnome.org
Michael Felt mamfelt@gmail.com Michael Felt mamfelt@gmail.com
Michael Hayes m.hayes@elec.canterbury.ac.nz Michael Hayes m.hayes@elec.canterbury.ac.nz
Michael Raskin 7c6f434c@mail.ru Michael Raskin 7c6f434c@mail.ru
Michel d'Hooge michel.dhooge@gmail.com
Michiel De Wilde mdewilde.agilent@gmail.com Michiel De Wilde mdewilde.agilent@gmail.com
Mickael Labau labau_m@epita.fr Mickael Labau labau_m@epita.fr
Mike Castle dalgoda@ix.netcom.com Mike Castle dalgoda@ix.netcom.com
Mike Sullivan Mike.sullivan@Oracle.COM
Neil Booth NeilB@earthling.net Neil Booth NeilB@earthling.net
Nelson H. F. Beebe beebe@math.utah.edu Nelson H. F. Beebe beebe@math.utah.edu
Nick Bowler nbowler@elliptictech.com Nick Bowler nbowler@elliptictech.com
Nicolas Bedon nicolas.bedon@univ-rouen.fr
Nicolas Burrus nicolas.burrus@epita.fr Nicolas Burrus nicolas.burrus@epita.fr
Nicolas Tisserand nicolas.tisserand@epita.fr Nicolas Tisserand nicolas.tisserand@epita.fr
Noah Friedman friedman@gnu.org Noah Friedman friedman@gnu.org
@@ -132,6 +137,7 @@ Steve Murphy murf@parsetree.com
Sum Wu sum@geekhouse.org Sum Wu sum@geekhouse.org
Théophile Ranquet theophile.ranquet@gmail.com Théophile Ranquet theophile.ranquet@gmail.com
Thiru Ramakrishnan thiru.ramakrishnan@gmail.com Thiru Ramakrishnan thiru.ramakrishnan@gmail.com
Thomas Jahns jahns@dkrz.de
Tim Josling tej@melbpc.org.au Tim Josling tej@melbpc.org.au
Tim Landscheidt tim@tim-landscheidt.de Tim Landscheidt tim@tim-landscheidt.de
Tim Van Holder tim.van.holder@pandora.be Tim Van Holder tim.van.holder@pandora.be

View File

@@ -174,9 +174,12 @@ m4_define([b4_public_types_declare],
/// (External) token type, as returned by yylex. /// (External) token type, as returned by yylex.
typedef token::yytokentype token_type; typedef token::yytokentype token_type;
/// Internal symbol number. /// Symbol type: an internal symbol number.
typedef int symbol_number_type; typedef int symbol_number_type;
/// The symbol type number to denote an empty symbol.
enum { empty_symbol = -2 };
/// Internal symbol number for tokens (subsumed by symbol_number_type). /// Internal symbol number for tokens (subsumed by symbol_number_type).
typedef ]b4_int_type_for([b4_translate])[ token_number_type; typedef ]b4_int_type_for([b4_translate])[ token_number_type;
@@ -209,8 +212,15 @@ m4_define([b4_public_types_declare],
const semantic_type& v]b4_locations_if([, const semantic_type& v]b4_locations_if([,
const location_type& l])[); const location_type& l])[);
/// Destroy the symbol.
~basic_symbol (); ~basic_symbol ();
/// Destroy contents, and record that is empty.
void clear ();
/// Whether empty.
bool empty () const;
/// Destructive move, \a s is emptied into this. /// Destructive move, \a s is emptied into this.
void move (basic_symbol& s); void move (basic_symbol& s);
@@ -240,21 +250,23 @@ m4_define([b4_public_types_declare],
/// Constructor from (external) token numbers. /// Constructor from (external) token numbers.
by_type (kind_type t); by_type (kind_type t);
/// Record that this symbol is empty.
void clear ();
/// Steal the symbol type from \a that. /// Steal the symbol type from \a that.
void move (by_type& that); void move (by_type& that);
/// The (internal) type number (corresponding to \a type). /// The (internal) type number (corresponding to \a type).
/// -1 when this symbol is empty. /// \a empty when empty.
symbol_number_type type_get () const; symbol_number_type type_get () const;
/// The token. /// The token.
token_type token () const; token_type token () const;
enum { empty = 0 };
/// The symbol type. /// The symbol type.
/// -1 when this symbol is empty. /// \a empty_symbol when empty.
token_number_type type; /// An int, not token_number_type, to be able to store empty_symbol.
int type;
}; };
/// "External" symbols: returned by the scanner. /// "External" symbols: returned by the scanner.
@@ -323,9 +335,18 @@ m4_define([b4_public_types_define],
template <typename Base> template <typename Base>
inline inline
]b4_parser_class_name[::basic_symbol<Base>::~basic_symbol () ]b4_parser_class_name[::basic_symbol<Base>::~basic_symbol ()
{
clear ();
}
template <typename Base>
inline
void
]b4_parser_class_name[::basic_symbol<Base>::clear ()
{]b4_variant_if([[ {]b4_variant_if([[
// User destructor. // User destructor.
symbol_number_type yytype = this->type_get (); symbol_number_type yytype = this->type_get ();
basic_symbol<Base>& yysym = *this;
switch (yytype) switch (yytype)
{ {
]b4_symbol_foreach([b4_symbol_destructor])dnl ]b4_symbol_foreach([b4_symbol_destructor])dnl
@@ -335,6 +356,15 @@ m4_define([b4_public_types_define],
// Type destructor. // Type destructor.
]b4_symbol_variant([[yytype]], [[value]], [[template destroy]])])[ ]b4_symbol_variant([[yytype]], [[value]], [[template destroy]])])[
Base::clear ();
}
template <typename Base>
inline
bool
]b4_parser_class_name[::basic_symbol<Base>::empty () const
{
return Base::type_get () == empty_symbol;
} }
template <typename Base> template <typename Base>
@@ -352,7 +382,7 @@ m4_define([b4_public_types_define],
// by_type. // by_type.
inline inline
]b4_parser_class_name[::by_type::by_type () ]b4_parser_class_name[::by_type::by_type ()
: type (empty) : type (empty_symbol)
{} {}
inline inline
@@ -365,12 +395,19 @@ m4_define([b4_public_types_define],
: type (yytranslate_ (t)) : type (yytranslate_ (t))
{} {}
inline
void
]b4_parser_class_name[::by_type::clear ()
{
type = empty_symbol;
}
inline inline
void void
]b4_parser_class_name[::by_type::move (by_type& that) ]b4_parser_class_name[::by_type::move (by_type& that)
{ {
type = that.type; type = that.type;
that.type = empty; that.clear ();
} }
inline inline

View File

@@ -214,9 +214,9 @@ b4_location_define])])[
/// Generate an error message. /// Generate an error message.
/// \param yystate the state where the error occurred. /// \param yystate the state where the error occurred.
/// \param yytoken the lookahead token type, or yyempty_. /// \param yyla the lookahead token.
virtual std::string yysyntax_error_ (state_type yystate, virtual std::string yysyntax_error_ (state_type yystate,
symbol_number_type yytoken) const; const symbol_type& yyla) const;
/// Compute post-reduction state. /// Compute post-reduction state.
/// \param yystate the current state /// \param yystate the current state
@@ -288,16 +288,21 @@ b4_location_define])])[
/// Copy constructor. /// Copy constructor.
by_state (const by_state& other); by_state (const by_state& other);
/// Record that this symbol is empty.
void clear ();
/// Steal the symbol type from \a that. /// Steal the symbol type from \a that.
void move (by_state& that); void move (by_state& that);
/// The (internal) type number (corresponding to \a state). /// The (internal) type number (corresponding to \a state).
/// "empty" when empty. /// \a empty_symbol when empty.
symbol_number_type type_get () const; symbol_number_type type_get () const;
enum { empty = 0 }; /// The state number used to denote an empty symbol.
enum { empty_state = -1 };
/// The state. /// The state.
/// \a empty when empty.
state_type state; state_type state;
}; };
@@ -338,13 +343,12 @@ b4_location_define])])[
/// Pop \a n symbols the three stacks. /// Pop \a n symbols the three stacks.
void yypop_ (unsigned int n = 1); void yypop_ (unsigned int n = 1);
// Constants. /// Constants.
enum enum
{ {
yyeof_ = 0, yyeof_ = 0,
yylast_ = ]b4_last[, ///< Last index in yytable_. yylast_ = ]b4_last[, ///< Last index in yytable_.
yynnts_ = ]b4_nterms_number[, ///< Number of nonterminal symbols. yynnts_ = ]b4_nterms_number[, ///< Number of nonterminal symbols.
yyempty_ = -2,
yyfinal_ = ]b4_final_state_number[, ///< Termination state number. yyfinal_ = ]b4_final_state_number[, ///< Termination state number.
yyterror_ = 1, yyterror_ = 1,
yyerrcode_ = 256, yyerrcode_ = 256,
@@ -464,7 +468,7 @@ m4_if(b4_prefix, [yy], [],
#endif // !]b4_api_PREFIX[DEBUG #endif // !]b4_api_PREFIX[DEBUG
#define yyerrok (yyerrstatus_ = 0) #define yyerrok (yyerrstatus_ = 0)
#define yyclearin (yyempty = true) #define yyclearin (yyla.clear ())
#define YYACCEPT goto yyacceptlab #define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab #define YYABORT goto yyabortlab
@@ -533,7 +537,7 @@ m4_if(b4_prefix, [yy], [],
// by_state. // by_state.
inline inline
]b4_parser_class_name[::by_state::by_state () ]b4_parser_class_name[::by_state::by_state ()
: state (empty) : state (empty_state)
{} {}
inline inline
@@ -541,12 +545,19 @@ m4_if(b4_prefix, [yy], [],
: state (other.state) : state (other.state)
{} {}
inline
void
]b4_parser_class_name[::by_state::clear ()
{
state = empty_state;
}
inline inline
void void
]b4_parser_class_name[::by_state::move (by_state& that) ]b4_parser_class_name[::by_state::move (by_state& that)
{ {
state = that.state; state = that.state;
that.state = empty; that.clear ();
} }
inline inline
@@ -558,7 +569,7 @@ m4_if(b4_prefix, [yy], [],
]b4_parser_class_name[::symbol_number_type ]b4_parser_class_name[::symbol_number_type
]b4_parser_class_name[::by_state::type_get () const ]b4_parser_class_name[::by_state::type_get () const
{ {
return state == empty ? 0 : yystos_[state]; return state == empty_state ? empty_symbol : yystos_[state];
} }
inline inline
@@ -574,7 +585,7 @@ m4_if(b4_prefix, [yy], [],
[value], [move], [that.value])], [value], [move], [that.value])],
[[value = that.value;]])[ [[value = that.value;]])[
// that is emptied. // that is emptied.
that.type = empty; that.type = empty_symbol;
} }
inline inline
@@ -695,9 +706,6 @@ m4_if(b4_prefix, [yy], [],
int int
]b4_parser_class_name[::parse () ]b4_parser_class_name[::parse ()
{ {
/// Whether yyla contains a lookahead.
bool yyempty = true;
// State. // State.
int yyn; int yyn;
/// Length of the RHS of the rule being reduced. /// Length of the RHS of the rule being reduced.
@@ -754,7 +762,7 @@ b4_dollar_popdef])[]dnl
goto yydefault; goto yydefault;
// Read a lookahead token. // Read a lookahead token.
if (yyempty) if (yyla.empty ())
{ {
YYCDEBUG << "Reading a token: "; YYCDEBUG << "Reading a token: ";
try try
@@ -768,7 +776,6 @@ b4_dollar_popdef])[]dnl
error (yyexc); error (yyexc);
goto yyerrlab1; goto yyerrlab1;
} }
yyempty = false;
} }
YY_SYMBOL_PRINT ("Next token is", yyla); YY_SYMBOL_PRINT ("Next token is", yyla);
@@ -788,9 +795,6 @@ b4_dollar_popdef])[]dnl
goto yyreduce; goto yyreduce;
} }
// Discard the token being shifted.
yyempty = true;
// Count tokens shifted since error; after three, turn off error status. // Count tokens shifted since error; after three, turn off error status.
if (yyerrstatus_) if (yyerrstatus_)
--yyerrstatus_; --yyerrstatus_;
@@ -873,8 +877,7 @@ b4_dollar_popdef])[]dnl
{ {
++yynerrs_; ++yynerrs_;
error (]b4_join(b4_locations_if([yyla.location]), error (]b4_join(b4_locations_if([yyla.location]),
[[yysyntax_error_ (yystack_[0].state, [[yysyntax_error_ (yystack_[0].state, yyla)]])[);
yyempty ? yyempty_ : yyla.type_get ())]])[);
} }
]b4_locations_if([[ ]b4_locations_if([[
@@ -887,10 +890,10 @@ b4_dollar_popdef])[]dnl
// Return failure if at end of input. // Return failure if at end of input.
if (yyla.type_get () == yyeof_) if (yyla.type_get () == yyeof_)
YYABORT; YYABORT;
else if (!yyempty) else if (!yyla.empty ())
{ {
yy_destroy_ ("Error: discarding", yyla); yy_destroy_ ("Error: discarding", yyla);
yyempty = true; yyla.clear ();
} }
} }
@@ -966,7 +969,7 @@ b4_dollar_popdef])[]dnl
goto yyreturn; goto yyreturn;
yyreturn: yyreturn:
if (!yyempty) if (!yyla.empty ())
yy_destroy_ ("Cleanup: discarding lookahead", yyla); yy_destroy_ ("Cleanup: discarding lookahead", yyla);
/* Do not reclaim the symbols of the rule whose action triggered /* Do not reclaim the symbols of the rule whose action triggered
@@ -986,7 +989,7 @@ b4_dollar_popdef])[]dnl
<< std::endl; << std::endl;
// Do not try to display the values of the reclaimed symbols, // Do not try to display the values of the reclaimed symbols,
// as their printer might throw an exception. // as their printer might throw an exception.
if (!yyempty) if (!yyla.empty ())
yy_destroy_ (YY_NULLPTR, yyla); yy_destroy_ (YY_NULLPTR, yyla);
while (1 < yystack_.size ()) while (1 < yystack_.size ())
@@ -1008,10 +1011,9 @@ b4_dollar_popdef])[]dnl
// Generate an error message. // Generate an error message.
std::string std::string
]b4_parser_class_name[::yysyntax_error_ (]dnl ]b4_parser_class_name[::yysyntax_error_ (]dnl
b4_error_verbose_if([state_type yystate, symbol_number_type yytoken], b4_error_verbose_if([state_type yystate, const symbol_type& yyla],
[state_type, symbol_number_type])[) const [state_type, const symbol_type&])[) const
{]b4_error_verbose_if([[ {]b4_error_verbose_if([[
std::string yyres;
// Number of reported tokens (one for the "unexpected", one per // Number of reported tokens (one for the "unexpected", one per
// "expected"). // "expected").
size_t yycount = 0; size_t yycount = 0;
@@ -1025,7 +1027,7 @@ b4_error_verbose_if([state_type yystate, symbol_number_type yytoken],
the only way this function was invoked is if the default action the only way this function was invoked is if the default action
is an error action. In that case, don't check for expected is an error action. In that case, don't check for expected
tokens because there are none. tokens because there are none.
- The only way there can be no lookahead present (in yytoken) is - The only way there can be no lookahead present (in yyla) is
if this state is a consistent state with a default action. if this state is a consistent state with a default action.
Thus, detecting the absence of a lookahead is sufficient to Thus, detecting the absence of a lookahead is sufficient to
determine that there is no unexpected or expected token to determine that there is no unexpected or expected token to
@@ -1045,8 +1047,9 @@ b4_error_verbose_if([state_type yystate, symbol_number_type yytoken],
token that will not be accepted due to an error action in a token that will not be accepted due to an error action in a
later state. later state.
*/ */
if (yytoken != yyempty_) if (!yyla.empty ())
{ {
int yytoken = yyla.type_get ();
yyarg[yycount++] = yytname_[yytoken]; yyarg[yycount++] = yytname_[yytoken];
int yyn = yypact_[yystate]; int yyn = yypact_[yystate];
if (!yy_pact_value_is_default_ (yyn)) if (!yy_pact_value_is_default_ (yyn))
@@ -1089,6 +1092,7 @@ b4_error_verbose_if([state_type yystate, symbol_number_type yytoken],
#undef YYCASE_ #undef YYCASE_
} }
std::string yyres;
// Argument number. // Argument number.
size_t yyi = 0; size_t yyi = 0;
for (char const* yyp = yyformat; *yyp; ++yyp) for (char const* yyp = yyformat; *yyp; ++yyp)

View File

@@ -83,7 +83,7 @@ m4_define([b4_position_define],
} }
}; };
/// Add and assign a position. /// Add \a width columns, in place.
inline position& inline position&
operator+= (position& res, int width) operator+= (position& res, int width)
{ {
@@ -91,21 +91,21 @@ m4_define([b4_position_define],
return res; return res;
} }
/// Add two position objects. /// Add \a width columns.
inline position inline position
operator+ (position res, int width) operator+ (position res, int width)
{ {
return res += width; return res += width;
} }
/// Add and assign a position. /// Subtract \a width columns, in place.
inline position& inline position&
operator-= (position& res, int width) operator-= (position& res, int width)
{ {
return res += -width; return res += -width;
} }
/// Add two position objects. /// Subtract \a width columns.
inline position inline position
operator- (position res, int width) operator- (position res, int width)
{ {
@@ -216,36 +216,42 @@ m4_define([b4_location_define],
position end; position end;
}; };
/// Join two location objects to create a location. /// Join two locations, in place.
inline location operator+ (location res, const location& end) inline location& operator+= (location& res, const location& end)
{ {
res.end = end.end; res.end = end.end;
return res; return res;
} }
/// Change end position in place. /// Join two locations.
inline location operator+ (location res, const location& end)
{
return res += end;
}
/// Add \a width columns to the end position, in place.
inline location& operator+= (location& res, int width) inline location& operator+= (location& res, int width)
{ {
res.columns (width); res.columns (width);
return res; return res;
} }
/// Change end position. /// Add \a width columns to the end position.
inline location operator+ (location res, int width) inline location operator+ (location res, int width)
{ {
return res += width; return res += width;
} }
/// Change end position in place. /// Subtract \a width columns to the end position, in place.
inline location& operator-= (location& res, int width) inline location& operator-= (location& res, int width)
{ {
return res += -width; return res += -width;
} }
/// Change end position. /// Subtract \a width columns to the end position.
inline location operator- (const location& begin, int width) inline location operator- (location res, int width)
{ {
return begin + -width; return res -= width;
} }
]b4_percent_define_flag_if([[define_location_comparison]], [[ ]b4_percent_define_flag_if([[define_location_comparison]], [[
/// Compare two location objects. /// Compare two location objects.

View File

@@ -95,13 +95,13 @@ m4_define([b4_variant_define],
/// Empty construction. /// Empty construction.
variant ()]b4_parse_assert_if([ variant ()]b4_parse_assert_if([
: yytname_ (YY_NULLPTR)])[ : yytypeid_ (YY_NULLPTR)])[
{} {}
/// Construct and fill. /// Construct and fill.
template <typename T> template <typename T>
variant (const T& t)]b4_parse_assert_if([ variant (const T& t)]b4_parse_assert_if([
: yytname_ (typeid (T).name ())])[ : yytypeid_ (&typeid (T))])[
{ {
YYASSERT (sizeof (T) <= S); YYASSERT (sizeof (T) <= S);
new (yyas_<T> ()) T (t); new (yyas_<T> ()) T (t);
@@ -110,7 +110,7 @@ m4_define([b4_variant_define],
/// Destruction, allowed only if empty. /// Destruction, allowed only if empty.
~variant () ~variant ()
{]b4_parse_assert_if([ {]b4_parse_assert_if([
YYASSERT (!yytname_); YYASSERT (!yytypeid_);
])[} ])[}
/// Instantiate an empty \a T in here. /// Instantiate an empty \a T in here.
@@ -118,9 +118,9 @@ m4_define([b4_variant_define],
T& T&
build () build ()
{]b4_parse_assert_if([ {]b4_parse_assert_if([
YYASSERT (!yytname_); YYASSERT (!yytypeid_);
YYASSERT (sizeof (T) <= S); YYASSERT (sizeof (T) <= S);
yytname_ = typeid (T).name ();])[ yytypeid_ = & typeid (T);])[
return *new (yyas_<T> ()) T; return *new (yyas_<T> ()) T;
} }
@@ -129,9 +129,9 @@ m4_define([b4_variant_define],
T& T&
build (const T& t) build (const T& t)
{]b4_parse_assert_if([ {]b4_parse_assert_if([
YYASSERT (!yytname_); YYASSERT (!yytypeid_);
YYASSERT (sizeof (T) <= S); YYASSERT (sizeof (T) <= S);
yytname_ = typeid (T).name ();])[ yytypeid_ = & typeid (T);])[
return *new (yyas_<T> ()) T (t); return *new (yyas_<T> ()) T (t);
} }
@@ -140,7 +140,7 @@ m4_define([b4_variant_define],
T& T&
as () as ()
{]b4_parse_assert_if([ {]b4_parse_assert_if([
YYASSERT (yytname_ == typeid (T).name ()); YYASSERT (*yytypeid_ == typeid (T));
YYASSERT (sizeof (T) <= S);])[ YYASSERT (sizeof (T) <= S);])[
return *yyas_<T> (); return *yyas_<T> ();
} }
@@ -150,7 +150,7 @@ m4_define([b4_variant_define],
const T& const T&
as () const as () const
{]b4_parse_assert_if([ {]b4_parse_assert_if([
YYASSERT (yytname_ == typeid (T).name ()); YYASSERT (*yytypeid_ == typeid (T));
YYASSERT (sizeof (T) <= S);])[ YYASSERT (sizeof (T) <= S);])[
return *yyas_<T> (); return *yyas_<T> ();
} }
@@ -167,8 +167,8 @@ m4_define([b4_variant_define],
void void
swap (self_type& other) swap (self_type& other)
{]b4_parse_assert_if([ {]b4_parse_assert_if([
YYASSERT (yytname_); YYASSERT (yytypeid_);
YYASSERT (yytname_ == other.yytname_);])[ YYASSERT (*yytypeid_ == *other.yytypeid_);])[
std::swap (as<T> (), other.as<T> ()); std::swap (as<T> (), other.as<T> ());
} }
@@ -198,7 +198,7 @@ m4_define([b4_variant_define],
destroy () destroy ()
{ {
as<T> ().~T ();]b4_parse_assert_if([ as<T> ().~T ();]b4_parse_assert_if([
yytname_ = YY_NULLPTR;])[ yytypeid_ = YY_NULLPTR;])[
} }
private: private:
@@ -233,7 +233,7 @@ m4_define([b4_variant_define],
} yybuffer_;]b4_parse_assert_if([ } yybuffer_;]b4_parse_assert_if([
/// Whether the content is built: if defined, the name of the stored type. /// Whether the content is built: if defined, the name of the stored type.
const char *yytname_;])[ const std::type_info *yytypeid_;])[
}; };
]]) ]])

View File

@@ -10382,9 +10382,23 @@ declare @code{yyerror} as follows:
int yyerror (char const *); int yyerror (char const *);
@end example @end example
Bison ignores the @code{int} value returned by this @code{yyerror}. @noindent
If you use the Yacc library's @code{main} function, your The @code{int} value returned by this @code{yyerror} is ignored.
@code{yyparse} function should have the following type signature:
The implementation of Yacc library's @code{main} function is:
@example
int main (void)
@{
setlocale (LC_ALL, "");
return yyparse ();
@}
@end example
@noindent
so if you use it, the internationalization support is enabled (e.g., error
messages are translated), and your @code{yyparse} function should have the
following type signature:
@example @example
int yyparse (void); int yyparse (void);
@@ -10686,12 +10700,17 @@ The first, inclusive, position of the range, and the first beyond.
Forwarded to the @code{end} position. Forwarded to the @code{end} position.
@end deftypemethod @end deftypemethod
@deftypemethod {location} {location} operator+ (const location& @var{end}) @deftypemethod {location} {location} operator+ (int @var{width})
@deftypemethodx {location} {location} operator+ (int @var{width})
@deftypemethodx {location} {location} operator+= (int @var{width}) @deftypemethodx {location} {location} operator+= (int @var{width})
@deftypemethodx {location} {location} operator- (int @var{width}) @deftypemethodx {location} {location} operator- (int @var{width})
@deftypemethodx {location} {location} operator-= (int @var{width}) @deftypemethodx {location} {location} operator-= (int @var{width})
Various forms of syntactic sugar. Various forms of syntactic sugar for @code{columns}.
@end deftypemethod
@deftypemethod {location} {location} operator+ (const location& @var{end})
@deftypemethodx {location} {location} operator+= (const location& @var{end})
Join two locations: starts at the position of the first one, and ends at the
position of the second.
@end deftypemethod @end deftypemethod
@deftypemethod {location} {void} step () @deftypemethod {location} {void} step ()

View File

@@ -132,7 +132,7 @@ endif
## Graphviz examples generation. ## ## Graphviz examples generation. ##
## ----------------------------- ## ## ----------------------------- ##
CLEANDIRS += doc/figs CLEANFILES += $(FIGS_GV:.gv=.eps) $(FIGS_GV:.gv=.pdf) $(FIGS_GV:.gv=.png)
FIGS_GV = \ FIGS_GV = \
doc/figs/example.gv \ doc/figs/example.gv \
doc/figs/example-reduce.gv doc/figs/example-shift.gv doc/figs/example-reduce.gv doc/figs/example-shift.gv

View File

@@ -15,7 +15,6 @@ src/reduce.c
src/scan-code.l src/scan-code.l
src/scan-gram.l src/scan-gram.l
src/scan-skel.l src/scan-skel.l
src/symlist.c
src/symtab.c src/symtab.c
djgpp/subpipe.c djgpp/subpipe.c

View File

@@ -711,7 +711,7 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
"]b4_rhs_value(%d, %d, ", effective_rule_length, n); "]b4_rhs_value(%d, %d, ", effective_rule_length, n);
obstack_quote (&obstack_for_string, type_name); obstack_quote (&obstack_for_string, type_name);
obstack_sgrow (&obstack_for_string, ")["); obstack_sgrow (&obstack_for_string, ")[");
if (n > 0) if (0 < n)
symbol_list_n_get (effective_rule, n)->action_props.is_value_used = symbol_list_n_get (effective_rule, n)->action_props.is_value_used =
true; true;
break; break;

View File

@@ -21,7 +21,6 @@
#include <config.h> #include <config.h>
#include "system.h" #include "system.h"
#include "complain.h"
#include "symlist.h" #include "symlist.h"
/*--------------------------------------. /*--------------------------------------.
@@ -174,22 +173,17 @@ symbol_list *
symbol_list_n_get (symbol_list *l, int n) symbol_list_n_get (symbol_list *l, int n)
{ {
int i; int i;
aver (0 <= n);
if (n < 0)
return NULL;
for (i = 0; i < n; ++i) for (i = 0; i < n; ++i)
{ {
l = l->next; l = l->next;
if (l == NULL aver (l);
|| (l->content_type == SYMLIST_SYMBOL && l->content.sym == NULL))
return NULL;
} }
aver (l->content_type == SYMLIST_SYMBOL);
aver (l->content.sym);
return l; return l;
} }
/*--------------------------------------------------------------. /*--------------------------------------------------------------.
| Get the data type (alternative in the union) of the value for | | Get the data type (alternative in the union) of the value for |
| symbol N in symbol list L. | | symbol N in symbol list L. |
@@ -198,21 +192,14 @@ symbol_list_n_get (symbol_list *l, int n)
uniqstr uniqstr
symbol_list_n_type_name_get (symbol_list *l, location loc, int n) symbol_list_n_type_name_get (symbol_list *l, location loc, int n)
{ {
l = symbol_list_n_get (l, n); return symbol_list_n_get (l, n)->content.sym->content->type_name;
if (!l)
{
complain (&loc, complaint, _("invalid $ value: $%d"), n);
return NULL;
}
aver (l->content_type == SYMLIST_SYMBOL);
return l->content.sym->content->type_name;
} }
bool bool
symbol_list_null (symbol_list *node) symbol_list_null (symbol_list *node)
{ {
return !node || return (!node
(node->content_type == SYMLIST_SYMBOL && !(node->content.sym)); || (node->content_type == SYMLIST_SYMBOL && !node->content.sym));
} }
void void

View File

@@ -116,7 +116,10 @@ void symbol_list_free (symbol_list *list);
/** Return the length of \c l. */ /** Return the length of \c l. */
int symbol_list_length (symbol_list const *l); int symbol_list_length (symbol_list const *l);
/** Get item \c n in symbol list \c l. */ /** Get item \c n in symbol list \c l.
** \pre 0 <= n
** \post res != NULL
**/
symbol_list *symbol_list_n_get (symbol_list *l, int n); symbol_list *symbol_list_n_get (symbol_list *l, int n);
/* Get the data type (alternative in the union) of the value for /* Get the data type (alternative in the union) of the value for

View File

@@ -60,8 +60,10 @@ main (void)
{ {
int fail = 0; int fail = 0;
]AT_YYLTYPE[ loc; fail += check (loc, "1.1"); ]AT_YYLTYPE[ loc; fail += check (loc, "1.1");
fail += check (loc + 10, "1.1-10");
loc += 10; fail += check (loc, "1.1-10"); loc += 10; fail += check (loc, "1.1-10");
loc += -5; fail += check (loc, "1.1-5"); loc += -5; fail += check (loc, "1.1-5");
fail += check (loc - 5, "1.1");
loc -= 5; fail += check (loc, "1.1"); loc -= 5; fail += check (loc, "1.1");
// Check that we don't go below. // Check that we don't go below.
// http://lists.gnu.org/archive/html/bug-bison/2013-02/msg00000.html // http://lists.gnu.org/archive/html/bug-bison/2013-02/msg00000.html
@@ -70,6 +72,11 @@ main (void)
loc.columns (10); loc.lines (10); fail += check (loc, "1.1-11.0"); loc.columns (10); loc.lines (10); fail += check (loc, "1.1-11.0");
loc.lines (-2); fail += check (loc, "1.1-9.0"); loc.lines (-2); fail += check (loc, "1.1-9.0");
loc.lines (-10); fail += check (loc, "1.1"); loc.lines (-10); fail += check (loc, "1.1");
]AT_YYLTYPE[ loc2 (YY_NULLPTR, 5, 10);
fail += check (loc2, "5.10");
fail += check (loc + loc2, "1.1-5.9");
loc += loc2; fail += check (loc, "1.1-5.9");
return !fail; return !fail;
} }
]]) ]])
@@ -168,6 +175,9 @@ AT_CLEANUP
## Variants. ## ## Variants. ##
## ---------- ## ## ---------- ##
# Check that the variants are properly supported, including in error
# recovery.
# AT_TEST([DIRECTIVES]) # AT_TEST([DIRECTIVES])
# --------------------- # ---------------------
# Check the support of variants in C++, with the additional DIRECTIVES. # Check the support of variants in C++, with the additional DIRECTIVES.
@@ -225,7 +235,7 @@ typedef std::list<std::string> strings_type;
template <typename T> template <typename T>
inline inline
std::string std::string
string_cast (const T& t) to_string (const T& t)
{ {
std::ostringstream o; std::ostringstream o;
o << t; o << t;
@@ -236,15 +246,18 @@ typedef std::list<std::string> strings_type;
%token <::std::string> TEXT; %token <::std::string> TEXT;
%token <int> NUMBER; %token <int> NUMBER;
%token END_OF_FILE 0; %token END_OF_FILE 0;
%token COMMA ","
%type <::std::string> item; %type <::std::string> item;
// Using the template type to exercize its parsing. // Using the template type to exercize its parsing.
// Starting with :: to ensure we don't output "<::" which starts by the // Starting with :: to ensure we don't output "<::" which starts by the
// digraph for the left square bracket. // digraph for the left square bracket.
%type <::std::list<std::string>> list result; %type <::std::list<std::string>> list;
%printer { yyo << $$; } %printer { yyo << $$; }
<int> <::std::string> <::std::list<std::string>>; <int> <::std::string> <::std::list<std::string>>;
%destructor { std::cerr << "Destroy: " << $$ << '\n'; } <*>;
%destructor { std::cerr << "Destroy: \"" << $$ << "\"\n"; } <::std::string>;
%% %%
result: result:
@@ -252,14 +265,14 @@ result:
; ;
list: list:
/* nothing */ { /* Generates an empty string list */ } item { $$.push_back ($][1); }
| list item { std::swap ($$,$][1); $$.push_back ($][2); } | list "," item { std::swap ($$, $][1); $$.push_back ($][3); }
| list error { std::swap ($$,$][1); } | list error { std::swap ($$, $][1); }
; ;
item: item:
TEXT { std::swap ($$,$][1); } TEXT { std::swap ($$, $][1); }
| NUMBER { if ($][1 == 3) YYERROR; else $$ = string_cast ($][1); } | NUMBER { if ($][1 == 3) YYERROR; else $$ = to_string ($][1); }
; ;
%% %%
]AT_TOKEN_CTOR_IF([], ]AT_TOKEN_CTOR_IF([],
@@ -278,30 +291,43 @@ namespace yy
parser::location_type* yylloc])[)]])[ parser::location_type* yylloc])[)]])[
{]AT_LOCATION_IF([ {]AT_LOCATION_IF([
typedef parser::location_type location;])[ typedef parser::location_type location;])[
static int stage = -1; // The 5 is a syntax error whose recovery requires that we discard
++stage; // the lookahead. This tests a regression, see
if (stage == STAGE_MAX) // <http://savannah.gnu.org/support/?108481>.
{]AT_TOKEN_CTOR_IF([[ static char const *input = "0,1,2,3,45,6";
switch (int stage = *input++)
{
case 0:]AT_TOKEN_CTOR_IF([[
return parser::make_END_OF_FILE (]AT_LOCATION_IF([location ()])[);]], return parser::make_END_OF_FILE (]AT_LOCATION_IF([location ()])[);]],
[AT_LOCATION_IF([ [AT_LOCATION_IF([
*yylloc = location ();])[ *yylloc = location ();])[
return parser::token::END_OF_FILE;]])[ return parser::token::END_OF_FILE;]])[
}
else if (stage % 2) case ',':
{]AT_TOKEN_CTOR_IF([[ ]AT_TOKEN_CTOR_IF([[
return parser::make_NUMBER (stage]AT_LOCATION_IF([, location ()])[);]], return parser::make_COMMA (]AT_LOCATION_IF([location ()])[);]], [[
[[ ]AT_LOCATION_IF([
yylval->BUILD (int, stage);]AT_LOCATION_IF([
*yylloc = location ();])[ *yylloc = location ();])[
return parser::token::NUMBER;]])[ return parser::token::COMMA;]])[
}
else default:
{]AT_TOKEN_CTOR_IF([[ stage = stage - '0';
return parser::make_TEXT (string_cast (stage)]AT_LOCATION_IF([, location ()])[);]], [[ if (stage % 2)
yylval->BUILD (std::string, string_cast (stage));]AT_LOCATION_IF([ {]AT_TOKEN_CTOR_IF([[
*yylloc = location ();])[ return parser::make_NUMBER (stage]AT_LOCATION_IF([, location ()])[);]], [[
return parser::token::TEXT;]])[ yylval->BUILD (int, stage);]AT_LOCATION_IF([
} *yylloc = location ();])[
return parser::token::NUMBER;]])[
}
else
{]AT_TOKEN_CTOR_IF([[
return parser::make_TEXT (to_string (stage)]AT_LOCATION_IF([, location ()])[);]], [[
yylval->BUILD (std::string, to_string (stage));]AT_LOCATION_IF([
*yylloc = location ();])[
return parser::token::TEXT;]])[
}
}
abort (); abort ();
} }
} }
@@ -312,8 +338,31 @@ namespace yy
AT_FULL_COMPILE([list]) AT_FULL_COMPILE([list])
AT_PARSER_CHECK([./list], 0, AT_PARSER_CHECK([./list], 0,
[(0, 1, 2, 4) [[(0, 1, 2, 4, 6)
]) ]],
[[Destroy: ""
Destroy: "0"
Destroy: (0)
Destroy: 1
Destroy: "1"
Destroy: ()
Destroy: ""
Destroy: "2"
Destroy: ()
Destroy: ""
Destroy: 3
Destroy: ()
Destroy: ""
Destroy: "4"
Destroy: ()
Destroy: ()
Destroy: 5
Destroy: ()
Destroy: ""
Destroy: "6"
Destroy: ()
Destroy: (0, 1, 2, 4, 6)
]])
AT_BISON_OPTION_POPDEFS AT_BISON_OPTION_POPDEFS
AT_CLEANUP AT_CLEANUP
@@ -321,11 +370,11 @@ AT_CLEANUP
AT_TEST([[%skeleton "lalr1.cc" ]]) AT_TEST([[%skeleton "lalr1.cc" ]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert]]) AT_TEST([[%skeleton "lalr1.cc" %define parse.assert]])
AT_TEST([[%skeleton "lalr1.cc" %locations %define parse.assert]]) AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %locations]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %code {\n#define TWO_STAGE_BUILD\n}]]) AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %code {\n#define TWO_STAGE_BUILD\n}]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor]]) AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_}]]) AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_}]])
AT_TEST([[%skeleton "lalr1.cc" %locations %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_}]]) AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_} %locations]])
m4_popdef([AT_TEST]) m4_popdef([AT_TEST])
@@ -345,6 +394,7 @@ AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
AT_DATA([input.yy], AT_DATA([input.yy],
[[%skeleton "lalr1.cc" [[%skeleton "lalr1.cc"
%locations %locations
%defines
%debug %debug
%% %%
exp: /* empty */; exp: /* empty */;
@@ -352,7 +402,7 @@ exp: /* empty */;
]AT_YYERROR_DEFINE[ ]AT_YYERROR_DEFINE[
]]) ]])
AT_BISON_CHECK([-o input.cc input.yy], 0) AT_BISON_CHECK([-o input.cc input.yy])
AT_DATA([Doxyfile], AT_DATA([Doxyfile],
[# The PROJECT_NAME tag is a single word (or a sequence of words [# The PROJECT_NAME tag is a single word (or a sequence of words
@@ -423,7 +473,7 @@ AT_CHECK_DOXYGEN([Private])
# so don't check compilation. # so don't check compilation.
m4_pushdef([AT_TEST], m4_pushdef([AT_TEST],
[AT_BISON_OPTION_PUSHDEFS([%language "C++" %define api.namespace {$1}]) [AT_BISON_OPTION_PUSHDEFS([%language "C++" %define api.namespace {$1}])
AT_DATA_GRAMMAR([[input.y]], AT_DATA_GRAMMAR([[input.yy]],
[[%language "C++" [[%language "C++"
%define api.namespace {]$1[} %define api.namespace {]$1[}
%union { int i; } %union { int i; }
@@ -455,10 +505,10 @@ void
]]) ]])
AT_BISON_CHECK([[-o input.cc input.y]]) AT_BISON_CHECK([[-o input.cc input.yy]])
m4_if([$#], [1], m4_if([$#], [1],
[AT_COMPILE_CXX([[input]], [[input.cc]]) [AT_COMPILE_CXX([[input]])
AT_PARSER_CHECK([[./input]])]) AT_PARSER_CHECK([[./input]])])
AT_BISON_OPTION_POPDEFS AT_BISON_OPTION_POPDEFS
]) ])
@@ -502,7 +552,7 @@ AT_SETUP([[Syntax error discarding no lookahead]])
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"]) AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
AT_DATA_GRAMMAR([[input.yy]], AT_DATA_GRAMMAR([[input.y]],
[[%skeleton "lalr1.cc" [[%skeleton "lalr1.cc"
%code { %code {
@@ -555,8 +605,7 @@ yy::parser::error (const std::string &m)
]AT_MAIN_DEFINE[ ]AT_MAIN_DEFINE[
]]) ]])
AT_BISON_CHECK([[-o input.cc input.yy]]) AT_FULL_COMPILE([[input]])
AT_COMPILE_CXX([[input]])
# This used to print "Discarding 'a'." again at the end. # This used to print "Discarding 'a'." again at the end.
AT_PARSER_CHECK([[./input]], [[1]], [[]], AT_PARSER_CHECK([[./input]], [[1]], [[]],
[[syntax error [[syntax error
@@ -576,7 +625,7 @@ AT_SETUP([[Syntax error as exception]])
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"]) AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
AT_DATA_GRAMMAR([[input.yy]], AT_DATA_GRAMMAR([[input.y]],
[[%skeleton "lalr1.cc" [[%skeleton "lalr1.cc"
%code %code
@@ -631,8 +680,7 @@ yy::parser::error (const std::string &m)
]AT_MAIN_DEFINE[ ]AT_MAIN_DEFINE[
]]) ]])
AT_BISON_CHECK([[-o input.cc input.yy]]) AT_FULL_COMPILE([[input]])
AT_COMPILE_CXX([[input]])
AT_PARSER_CHECK([[./input]], [[0]], [[]], AT_PARSER_CHECK([[./input]], [[0]], [[]],
[[error: invalid expression [[error: invalid expression
@@ -803,10 +851,10 @@ list:
item: item:
'a' { $$ = $][1; } 'a' { $$ = $][1; }
| 'e' { YYUSE ($$); YYUSE($][1); error ("syntax error"); } | 'e' { YYUSE ($$); YYUSE ($][1); error ("syntax error"); }
// Not just 'E', otherwise we reduce when 'E' is the lookahead, and // Not just 'E', otherwise we reduce when 'E' is the lookahead, and
// then the stack is emptied, defeating the point of the test. // then the stack is emptied, defeating the point of the test.
| 'E' 'a' { YYUSE($][1); $$ = $][2; } | 'E' 'a' { YYUSE ($][1); $$ = $][2; }
| 'R' { ]AT_VARIANT_IF([], [$$ = YY_NULLPTR; delete $][1]; )[YYERROR; } | 'R' { ]AT_VARIANT_IF([], [$$ = YY_NULLPTR; delete $][1]; )[YYERROR; }
| 'p' { $$ = $][1; } | 'p' { $$ = $][1; }
| 's' { $$ = $][1; throw std::runtime_error ("reduction"); } | 's' { $$ = $][1; throw std::runtime_error ("reduction"); }
@@ -929,9 +977,9 @@ AT_TEST([%define api.value.type variant], [without])
m4_popdef([AT_TEST]) m4_popdef([AT_TEST])
## ------------------------------------ ## ## ------------------------------------- ##
## C++ GLR parser identifier shadowing ## ## C++ GLR parser identifier shadowing. ##
## ------------------------------------ ## ## ------------------------------------- ##
AT_SETUP([[C++ GLR parser identifier shadowing]]) AT_SETUP([[C++ GLR parser identifier shadowing]])
@@ -967,7 +1015,7 @@ int yylex (yy::parser::semantic_type *yylval)
void yy::parser::error (std::string const&) void yy::parser::error (std::string const&)
{} {}
int main() int main ()
{} {}
]) ])

View File

@@ -393,10 +393,10 @@ AT_CLEANUP
## parse.error=verbose and consistent errors. ## ## parse.error=verbose and consistent errors. ##
## ------------------------------------------- ## ## ------------------------------------------- ##
AT_SETUP([[parse.error=verbose and consistent errors]])
m4_pushdef([AT_CONSISTENT_ERRORS_CHECK], [ m4_pushdef([AT_CONSISTENT_ERRORS_CHECK], [
AT_SETUP([[parse.error=verbose and consistent errors: $1]])
AT_BISON_OPTION_PUSHDEFS([$1]) AT_BISON_OPTION_PUSHDEFS([$1])
m4_pushdef([AT_YYLEX_PROTOTYPE], m4_pushdef([AT_YYLEX_PROTOTYPE],
@@ -483,7 +483,11 @@ m4_popdef([AT_EXPECTING])
m4_popdef([AT_YYLEX_PROTOTYPE]) m4_popdef([AT_YYLEX_PROTOTYPE])
AT_BISON_OPTION_POPDEFS AT_BISON_OPTION_POPDEFS
]) AT_CLEANUP
]) dnl AT_CONSISTENT_ERRORS_CHECK
m4_pushdef([AT_PREVIOUS_STATE_GRAMMAR], m4_pushdef([AT_PREVIOUS_STATE_GRAMMAR],
[[%nonassoc 'a'; [[%nonassoc 'a';
@@ -653,7 +657,6 @@ m4_popdef([AT_USER_ACTION_INPUT])
m4_popdef([AT_CONSISTENT_ERRORS_CHECK]) m4_popdef([AT_CONSISTENT_ERRORS_CHECK])
AT_CLEANUP