mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-23 19:23:02 +00:00
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:
14
NEWS
14
NEWS
@@ -4,19 +4,23 @@ GNU Bison NEWS
|
||||
|
||||
** 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
|
||||
|
||||
%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.
|
||||
|
||||
*** %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
|
||||
together with "%define api.value.type union".
|
||||
The C parsers were broken when %defines was used together with "%define
|
||||
api.value.type union".
|
||||
|
||||
*** Redeclarations are reported in proper order
|
||||
|
||||
|
||||
@@ -103,15 +103,17 @@ to perform the first checkout of the submodules, run
|
||||
|
||||
$ git submodule update --init
|
||||
|
||||
Git submodule support is weak before versions 1.6 and later, you
|
||||
should probably upgrade Git if your version is older.
|
||||
Git submodule support is weak before versions 1.6 and later, upgrade Git if
|
||||
your version is older.
|
||||
|
||||
The next step is to get other files needed to build, which are
|
||||
extracted from other source packages:
|
||||
|
||||
$ ./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
|
||||
$ make
|
||||
|
||||
6
THANKS
6
THANKS
@@ -12,6 +12,7 @@ Andreas Schwab schwab@suse.de
|
||||
Andrew Suffield asuffield@users.sourceforge.net
|
||||
Angelo Borsotti angelo.borsotti@gmail.com
|
||||
Anthony Heading ajrh@ajrh.net
|
||||
Antonio Silva Correia amsilvacorreia@hotmail.com
|
||||
Arnold Robbins arnold@skeeve.com
|
||||
Art Haas ahaas@neosoft.com
|
||||
Baron Schwartz baron@sequent.org
|
||||
@@ -82,15 +83,19 @@ Martin Mokrejs mmokrejs@natur.cuni.cz
|
||||
Martin Nylin martin.nylin@linuxmail.org
|
||||
Matt Kraai kraai@alumni.cmu.edu
|
||||
Matt Rosing rosing@peakfive.com
|
||||
Michael Catanzaro mcatanzaro@gnome.org
|
||||
Michael Felt mamfelt@gmail.com
|
||||
Michael Hayes m.hayes@elec.canterbury.ac.nz
|
||||
Michael Raskin 7c6f434c@mail.ru
|
||||
Michel d'Hooge michel.dhooge@gmail.com
|
||||
Michiel De Wilde mdewilde.agilent@gmail.com
|
||||
Mickael Labau labau_m@epita.fr
|
||||
Mike Castle dalgoda@ix.netcom.com
|
||||
Mike Sullivan Mike.sullivan@Oracle.COM
|
||||
Neil Booth NeilB@earthling.net
|
||||
Nelson H. F. Beebe beebe@math.utah.edu
|
||||
Nick Bowler nbowler@elliptictech.com
|
||||
Nicolas Bedon nicolas.bedon@univ-rouen.fr
|
||||
Nicolas Burrus nicolas.burrus@epita.fr
|
||||
Nicolas Tisserand nicolas.tisserand@epita.fr
|
||||
Noah Friedman friedman@gnu.org
|
||||
@@ -132,6 +137,7 @@ Steve Murphy murf@parsetree.com
|
||||
Sum Wu sum@geekhouse.org
|
||||
Théophile Ranquet theophile.ranquet@gmail.com
|
||||
Thiru Ramakrishnan thiru.ramakrishnan@gmail.com
|
||||
Thomas Jahns jahns@dkrz.de
|
||||
Tim Josling tej@melbpc.org.au
|
||||
Tim Landscheidt tim@tim-landscheidt.de
|
||||
Tim Van Holder tim.van.holder@pandora.be
|
||||
|
||||
53
data/c++.m4
53
data/c++.m4
@@ -174,9 +174,12 @@ m4_define([b4_public_types_declare],
|
||||
/// (External) token type, as returned by yylex.
|
||||
typedef token::yytokentype token_type;
|
||||
|
||||
/// Internal symbol number.
|
||||
/// Symbol type: an internal symbol number.
|
||||
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).
|
||||
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 location_type& l])[);
|
||||
|
||||
/// Destroy the 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.
|
||||
void move (basic_symbol& s);
|
||||
|
||||
@@ -240,21 +250,23 @@ m4_define([b4_public_types_declare],
|
||||
/// Constructor from (external) token numbers.
|
||||
by_type (kind_type t);
|
||||
|
||||
/// Record that this symbol is empty.
|
||||
void clear ();
|
||||
|
||||
/// Steal the symbol type from \a that.
|
||||
void move (by_type& that);
|
||||
|
||||
/// The (internal) type number (corresponding to \a type).
|
||||
/// -1 when this symbol is empty.
|
||||
/// \a empty when empty.
|
||||
symbol_number_type type_get () const;
|
||||
|
||||
/// The token.
|
||||
token_type token () const;
|
||||
|
||||
enum { empty = 0 };
|
||||
|
||||
/// The symbol type.
|
||||
/// -1 when this symbol is empty.
|
||||
token_number_type type;
|
||||
/// \a empty_symbol when empty.
|
||||
/// An int, not token_number_type, to be able to store empty_symbol.
|
||||
int type;
|
||||
};
|
||||
|
||||
/// "External" symbols: returned by the scanner.
|
||||
@@ -323,9 +335,18 @@ m4_define([b4_public_types_define],
|
||||
template <typename Base>
|
||||
inline
|
||||
]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([[
|
||||
// User destructor.
|
||||
symbol_number_type yytype = this->type_get ();
|
||||
basic_symbol<Base>& yysym = *this;
|
||||
switch (yytype)
|
||||
{
|
||||
]b4_symbol_foreach([b4_symbol_destructor])dnl
|
||||
@@ -335,6 +356,15 @@ m4_define([b4_public_types_define],
|
||||
|
||||
// Type destructor.
|
||||
]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>
|
||||
@@ -352,7 +382,7 @@ m4_define([b4_public_types_define],
|
||||
// by_type.
|
||||
inline
|
||||
]b4_parser_class_name[::by_type::by_type ()
|
||||
: type (empty)
|
||||
: type (empty_symbol)
|
||||
{}
|
||||
|
||||
inline
|
||||
@@ -365,12 +395,19 @@ m4_define([b4_public_types_define],
|
||||
: type (yytranslate_ (t))
|
||||
{}
|
||||
|
||||
inline
|
||||
void
|
||||
]b4_parser_class_name[::by_type::clear ()
|
||||
{
|
||||
type = empty_symbol;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
]b4_parser_class_name[::by_type::move (by_type& that)
|
||||
{
|
||||
type = that.type;
|
||||
that.type = empty;
|
||||
that.clear ();
|
||||
}
|
||||
|
||||
inline
|
||||
|
||||
@@ -214,9 +214,9 @@ b4_location_define])])[
|
||||
|
||||
/// Generate an error message.
|
||||
/// \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,
|
||||
symbol_number_type yytoken) const;
|
||||
const symbol_type& yyla) const;
|
||||
|
||||
/// Compute post-reduction state.
|
||||
/// \param yystate the current state
|
||||
@@ -288,16 +288,21 @@ b4_location_define])])[
|
||||
/// Copy constructor.
|
||||
by_state (const by_state& other);
|
||||
|
||||
/// Record that this symbol is empty.
|
||||
void clear ();
|
||||
|
||||
/// Steal the symbol type from \a that.
|
||||
void move (by_state& that);
|
||||
|
||||
/// The (internal) type number (corresponding to \a state).
|
||||
/// "empty" when empty.
|
||||
/// \a empty_symbol when empty.
|
||||
symbol_number_type type_get () const;
|
||||
|
||||
enum { empty = 0 };
|
||||
/// The state number used to denote an empty symbol.
|
||||
enum { empty_state = -1 };
|
||||
|
||||
/// The state.
|
||||
/// \a empty when empty.
|
||||
state_type state;
|
||||
};
|
||||
|
||||
@@ -338,13 +343,12 @@ b4_location_define])])[
|
||||
/// Pop \a n symbols the three stacks.
|
||||
void yypop_ (unsigned int n = 1);
|
||||
|
||||
// Constants.
|
||||
/// Constants.
|
||||
enum
|
||||
{
|
||||
yyeof_ = 0,
|
||||
yylast_ = ]b4_last[, ///< Last index in yytable_.
|
||||
yynnts_ = ]b4_nterms_number[, ///< Number of nonterminal symbols.
|
||||
yyempty_ = -2,
|
||||
yyfinal_ = ]b4_final_state_number[, ///< Termination state number.
|
||||
yyterror_ = 1,
|
||||
yyerrcode_ = 256,
|
||||
@@ -464,7 +468,7 @@ m4_if(b4_prefix, [yy], [],
|
||||
#endif // !]b4_api_PREFIX[DEBUG
|
||||
|
||||
#define yyerrok (yyerrstatus_ = 0)
|
||||
#define yyclearin (yyempty = true)
|
||||
#define yyclearin (yyla.clear ())
|
||||
|
||||
#define YYACCEPT goto yyacceptlab
|
||||
#define YYABORT goto yyabortlab
|
||||
@@ -533,7 +537,7 @@ m4_if(b4_prefix, [yy], [],
|
||||
// by_state.
|
||||
inline
|
||||
]b4_parser_class_name[::by_state::by_state ()
|
||||
: state (empty)
|
||||
: state (empty_state)
|
||||
{}
|
||||
|
||||
inline
|
||||
@@ -541,12 +545,19 @@ m4_if(b4_prefix, [yy], [],
|
||||
: state (other.state)
|
||||
{}
|
||||
|
||||
inline
|
||||
void
|
||||
]b4_parser_class_name[::by_state::clear ()
|
||||
{
|
||||
state = empty_state;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
]b4_parser_class_name[::by_state::move (by_state& that)
|
||||
{
|
||||
state = that.state;
|
||||
that.state = empty;
|
||||
that.clear ();
|
||||
}
|
||||
|
||||
inline
|
||||
@@ -558,7 +569,7 @@ m4_if(b4_prefix, [yy], [],
|
||||
]b4_parser_class_name[::symbol_number_type
|
||||
]b4_parser_class_name[::by_state::type_get () const
|
||||
{
|
||||
return state == empty ? 0 : yystos_[state];
|
||||
return state == empty_state ? empty_symbol : yystos_[state];
|
||||
}
|
||||
|
||||
inline
|
||||
@@ -574,7 +585,7 @@ m4_if(b4_prefix, [yy], [],
|
||||
[value], [move], [that.value])],
|
||||
[[value = that.value;]])[
|
||||
// that is emptied.
|
||||
that.type = empty;
|
||||
that.type = empty_symbol;
|
||||
}
|
||||
|
||||
inline
|
||||
@@ -695,9 +706,6 @@ m4_if(b4_prefix, [yy], [],
|
||||
int
|
||||
]b4_parser_class_name[::parse ()
|
||||
{
|
||||
/// Whether yyla contains a lookahead.
|
||||
bool yyempty = true;
|
||||
|
||||
// State.
|
||||
int yyn;
|
||||
/// Length of the RHS of the rule being reduced.
|
||||
@@ -754,7 +762,7 @@ b4_dollar_popdef])[]dnl
|
||||
goto yydefault;
|
||||
|
||||
// Read a lookahead token.
|
||||
if (yyempty)
|
||||
if (yyla.empty ())
|
||||
{
|
||||
YYCDEBUG << "Reading a token: ";
|
||||
try
|
||||
@@ -768,7 +776,6 @@ b4_dollar_popdef])[]dnl
|
||||
error (yyexc);
|
||||
goto yyerrlab1;
|
||||
}
|
||||
yyempty = false;
|
||||
}
|
||||
YY_SYMBOL_PRINT ("Next token is", yyla);
|
||||
|
||||
@@ -788,9 +795,6 @@ b4_dollar_popdef])[]dnl
|
||||
goto yyreduce;
|
||||
}
|
||||
|
||||
// Discard the token being shifted.
|
||||
yyempty = true;
|
||||
|
||||
// Count tokens shifted since error; after three, turn off error status.
|
||||
if (yyerrstatus_)
|
||||
--yyerrstatus_;
|
||||
@@ -873,8 +877,7 @@ b4_dollar_popdef])[]dnl
|
||||
{
|
||||
++yynerrs_;
|
||||
error (]b4_join(b4_locations_if([yyla.location]),
|
||||
[[yysyntax_error_ (yystack_[0].state,
|
||||
yyempty ? yyempty_ : yyla.type_get ())]])[);
|
||||
[[yysyntax_error_ (yystack_[0].state, yyla)]])[);
|
||||
}
|
||||
|
||||
]b4_locations_if([[
|
||||
@@ -887,10 +890,10 @@ b4_dollar_popdef])[]dnl
|
||||
// Return failure if at end of input.
|
||||
if (yyla.type_get () == yyeof_)
|
||||
YYABORT;
|
||||
else if (!yyempty)
|
||||
else if (!yyla.empty ())
|
||||
{
|
||||
yy_destroy_ ("Error: discarding", yyla);
|
||||
yyempty = true;
|
||||
yyla.clear ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -966,7 +969,7 @@ b4_dollar_popdef])[]dnl
|
||||
goto yyreturn;
|
||||
|
||||
yyreturn:
|
||||
if (!yyempty)
|
||||
if (!yyla.empty ())
|
||||
yy_destroy_ ("Cleanup: discarding lookahead", yyla);
|
||||
|
||||
/* Do not reclaim the symbols of the rule whose action triggered
|
||||
@@ -986,7 +989,7 @@ b4_dollar_popdef])[]dnl
|
||||
<< std::endl;
|
||||
// Do not try to display the values of the reclaimed symbols,
|
||||
// as their printer might throw an exception.
|
||||
if (!yyempty)
|
||||
if (!yyla.empty ())
|
||||
yy_destroy_ (YY_NULLPTR, yyla);
|
||||
|
||||
while (1 < yystack_.size ())
|
||||
@@ -1008,10 +1011,9 @@ b4_dollar_popdef])[]dnl
|
||||
// Generate an error message.
|
||||
std::string
|
||||
]b4_parser_class_name[::yysyntax_error_ (]dnl
|
||||
b4_error_verbose_if([state_type yystate, symbol_number_type yytoken],
|
||||
[state_type, symbol_number_type])[) const
|
||||
b4_error_verbose_if([state_type yystate, const symbol_type& yyla],
|
||||
[state_type, const symbol_type&])[) const
|
||||
{]b4_error_verbose_if([[
|
||||
std::string yyres;
|
||||
// Number of reported tokens (one for the "unexpected", one per
|
||||
// "expected").
|
||||
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
|
||||
is an error action. In that case, don't check for expected
|
||||
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.
|
||||
Thus, detecting the absence of a lookahead is sufficient 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
|
||||
later state.
|
||||
*/
|
||||
if (yytoken != yyempty_)
|
||||
if (!yyla.empty ())
|
||||
{
|
||||
int yytoken = yyla.type_get ();
|
||||
yyarg[yycount++] = yytname_[yytoken];
|
||||
int yyn = yypact_[yystate];
|
||||
if (!yy_pact_value_is_default_ (yyn))
|
||||
@@ -1089,6 +1092,7 @@ b4_error_verbose_if([state_type yystate, symbol_number_type yytoken],
|
||||
#undef YYCASE_
|
||||
}
|
||||
|
||||
std::string yyres;
|
||||
// Argument number.
|
||||
size_t yyi = 0;
|
||||
for (char const* yyp = yyformat; *yyp; ++yyp)
|
||||
|
||||
@@ -83,7 +83,7 @@ m4_define([b4_position_define],
|
||||
}
|
||||
};
|
||||
|
||||
/// Add and assign a position.
|
||||
/// Add \a width columns, in place.
|
||||
inline position&
|
||||
operator+= (position& res, int width)
|
||||
{
|
||||
@@ -91,21 +91,21 @@ m4_define([b4_position_define],
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add two position objects.
|
||||
/// Add \a width columns.
|
||||
inline position
|
||||
operator+ (position res, int width)
|
||||
{
|
||||
return res += width;
|
||||
}
|
||||
|
||||
/// Add and assign a position.
|
||||
/// Subtract \a width columns, in place.
|
||||
inline position&
|
||||
operator-= (position& res, int width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
/// Add two position objects.
|
||||
/// Subtract \a width columns.
|
||||
inline position
|
||||
operator- (position res, int width)
|
||||
{
|
||||
@@ -216,36 +216,42 @@ m4_define([b4_location_define],
|
||||
position end;
|
||||
};
|
||||
|
||||
/// Join two location objects to create a location.
|
||||
inline location operator+ (location res, const location& end)
|
||||
/// Join two locations, in place.
|
||||
inline location& operator+= (location& res, const location& end)
|
||||
{
|
||||
res.end = end.end;
|
||||
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)
|
||||
{
|
||||
res.columns (width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Change end position.
|
||||
/// Add \a width columns to the end position.
|
||||
inline location operator+ (location res, int 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)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
/// Change end position.
|
||||
inline location operator- (const location& begin, int width)
|
||||
/// Subtract \a width columns to the end position.
|
||||
inline location operator- (location res, int width)
|
||||
{
|
||||
return begin + -width;
|
||||
return res -= width;
|
||||
}
|
||||
]b4_percent_define_flag_if([[define_location_comparison]], [[
|
||||
/// Compare two location objects.
|
||||
|
||||
@@ -95,13 +95,13 @@ m4_define([b4_variant_define],
|
||||
|
||||
/// Empty construction.
|
||||
variant ()]b4_parse_assert_if([
|
||||
: yytname_ (YY_NULLPTR)])[
|
||||
: yytypeid_ (YY_NULLPTR)])[
|
||||
{}
|
||||
|
||||
/// Construct and fill.
|
||||
template <typename T>
|
||||
variant (const T& t)]b4_parse_assert_if([
|
||||
: yytname_ (typeid (T).name ())])[
|
||||
: yytypeid_ (&typeid (T))])[
|
||||
{
|
||||
YYASSERT (sizeof (T) <= S);
|
||||
new (yyas_<T> ()) T (t);
|
||||
@@ -110,7 +110,7 @@ m4_define([b4_variant_define],
|
||||
/// Destruction, allowed only if empty.
|
||||
~variant ()
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (!yytname_);
|
||||
YYASSERT (!yytypeid_);
|
||||
])[}
|
||||
|
||||
/// Instantiate an empty \a T in here.
|
||||
@@ -118,9 +118,9 @@ m4_define([b4_variant_define],
|
||||
T&
|
||||
build ()
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (!yytname_);
|
||||
YYASSERT (!yytypeid_);
|
||||
YYASSERT (sizeof (T) <= S);
|
||||
yytname_ = typeid (T).name ();])[
|
||||
yytypeid_ = & typeid (T);])[
|
||||
return *new (yyas_<T> ()) T;
|
||||
}
|
||||
|
||||
@@ -129,9 +129,9 @@ m4_define([b4_variant_define],
|
||||
T&
|
||||
build (const T& t)
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (!yytname_);
|
||||
YYASSERT (!yytypeid_);
|
||||
YYASSERT (sizeof (T) <= S);
|
||||
yytname_ = typeid (T).name ();])[
|
||||
yytypeid_ = & typeid (T);])[
|
||||
return *new (yyas_<T> ()) T (t);
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ m4_define([b4_variant_define],
|
||||
T&
|
||||
as ()
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (yytname_ == typeid (T).name ());
|
||||
YYASSERT (*yytypeid_ == typeid (T));
|
||||
YYASSERT (sizeof (T) <= S);])[
|
||||
return *yyas_<T> ();
|
||||
}
|
||||
@@ -150,7 +150,7 @@ m4_define([b4_variant_define],
|
||||
const T&
|
||||
as () const
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (yytname_ == typeid (T).name ());
|
||||
YYASSERT (*yytypeid_ == typeid (T));
|
||||
YYASSERT (sizeof (T) <= S);])[
|
||||
return *yyas_<T> ();
|
||||
}
|
||||
@@ -167,8 +167,8 @@ m4_define([b4_variant_define],
|
||||
void
|
||||
swap (self_type& other)
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (yytname_);
|
||||
YYASSERT (yytname_ == other.yytname_);])[
|
||||
YYASSERT (yytypeid_);
|
||||
YYASSERT (*yytypeid_ == *other.yytypeid_);])[
|
||||
std::swap (as<T> (), other.as<T> ());
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ m4_define([b4_variant_define],
|
||||
destroy ()
|
||||
{
|
||||
as<T> ().~T ();]b4_parse_assert_if([
|
||||
yytname_ = YY_NULLPTR;])[
|
||||
yytypeid_ = YY_NULLPTR;])[
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -233,7 +233,7 @@ m4_define([b4_variant_define],
|
||||
} yybuffer_;]b4_parse_assert_if([
|
||||
|
||||
/// Whether the content is built: if defined, the name of the stored type.
|
||||
const char *yytname_;])[
|
||||
const std::type_info *yytypeid_;])[
|
||||
};
|
||||
]])
|
||||
|
||||
|
||||
@@ -10382,9 +10382,23 @@ declare @code{yyerror} as follows:
|
||||
int yyerror (char const *);
|
||||
@end example
|
||||
|
||||
Bison ignores the @code{int} value returned by this @code{yyerror}.
|
||||
If you use the Yacc library's @code{main} function, your
|
||||
@code{yyparse} function should have the following type signature:
|
||||
@noindent
|
||||
The @code{int} value returned by this @code{yyerror} is ignored.
|
||||
|
||||
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
|
||||
int yyparse (void);
|
||||
@@ -10686,12 +10700,17 @@ The first, inclusive, position of the range, and the first beyond.
|
||||
Forwarded to the @code{end} position.
|
||||
@end deftypemethod
|
||||
|
||||
@deftypemethod {location} {location} operator+ (const location& @var{end})
|
||||
@deftypemethodx {location} {location} operator+ (int @var{width})
|
||||
@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})
|
||||
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
|
||||
|
||||
@deftypemethod {location} {void} step ()
|
||||
|
||||
@@ -132,7 +132,7 @@ endif
|
||||
## Graphviz examples generation. ##
|
||||
## ----------------------------- ##
|
||||
|
||||
CLEANDIRS += doc/figs
|
||||
CLEANFILES += $(FIGS_GV:.gv=.eps) $(FIGS_GV:.gv=.pdf) $(FIGS_GV:.gv=.png)
|
||||
FIGS_GV = \
|
||||
doc/figs/example.gv \
|
||||
doc/figs/example-reduce.gv doc/figs/example-shift.gv
|
||||
|
||||
@@ -15,7 +15,6 @@ src/reduce.c
|
||||
src/scan-code.l
|
||||
src/scan-gram.l
|
||||
src/scan-skel.l
|
||||
src/symlist.c
|
||||
src/symtab.c
|
||||
|
||||
djgpp/subpipe.c
|
||||
|
||||
@@ -711,7 +711,7 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
|
||||
"]b4_rhs_value(%d, %d, ", effective_rule_length, n);
|
||||
obstack_quote (&obstack_for_string, type_name);
|
||||
obstack_sgrow (&obstack_for_string, ")[");
|
||||
if (n > 0)
|
||||
if (0 < n)
|
||||
symbol_list_n_get (effective_rule, n)->action_props.is_value_used =
|
||||
true;
|
||||
break;
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <config.h>
|
||||
#include "system.h"
|
||||
|
||||
#include "complain.h"
|
||||
#include "symlist.h"
|
||||
|
||||
/*--------------------------------------.
|
||||
@@ -174,22 +173,17 @@ symbol_list *
|
||||
symbol_list_n_get (symbol_list *l, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (n < 0)
|
||||
return NULL;
|
||||
|
||||
aver (0 <= n);
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
l = l->next;
|
||||
if (l == NULL
|
||||
|| (l->content_type == SYMLIST_SYMBOL && l->content.sym == NULL))
|
||||
return NULL;
|
||||
aver (l);
|
||||
}
|
||||
|
||||
aver (l->content_type == SYMLIST_SYMBOL);
|
||||
aver (l->content.sym);
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------.
|
||||
| Get the data type (alternative in the union) of the value for |
|
||||
| symbol N in symbol list L. |
|
||||
@@ -198,21 +192,14 @@ symbol_list_n_get (symbol_list *l, int n)
|
||||
uniqstr
|
||||
symbol_list_n_type_name_get (symbol_list *l, location loc, int n)
|
||||
{
|
||||
l = symbol_list_n_get (l, n);
|
||||
if (!l)
|
||||
{
|
||||
complain (&loc, complaint, _("invalid $ value: $%d"), n);
|
||||
return NULL;
|
||||
}
|
||||
aver (l->content_type == SYMLIST_SYMBOL);
|
||||
return l->content.sym->content->type_name;
|
||||
return symbol_list_n_get (l, n)->content.sym->content->type_name;
|
||||
}
|
||||
|
||||
bool
|
||||
symbol_list_null (symbol_list *node)
|
||||
{
|
||||
return !node ||
|
||||
(node->content_type == SYMLIST_SYMBOL && !(node->content.sym));
|
||||
return (!node
|
||||
|| (node->content_type == SYMLIST_SYMBOL && !node->content.sym));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -116,7 +116,10 @@ void symbol_list_free (symbol_list *list);
|
||||
/** Return the length of \c 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);
|
||||
|
||||
/* Get the data type (alternative in the union) of the value for
|
||||
|
||||
140
tests/c++.at
140
tests/c++.at
@@ -60,8 +60,10 @@ main (void)
|
||||
{
|
||||
int fail = 0;
|
||||
]AT_YYLTYPE[ loc; fail += check (loc, "1.1");
|
||||
fail += check (loc + 10, "1.1-10");
|
||||
loc += 10; fail += check (loc, "1.1-10");
|
||||
loc += -5; fail += check (loc, "1.1-5");
|
||||
fail += check (loc - 5, "1.1");
|
||||
loc -= 5; fail += check (loc, "1.1");
|
||||
// Check that we don't go below.
|
||||
// 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.lines (-2); fail += check (loc, "1.1-9.0");
|
||||
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;
|
||||
}
|
||||
]])
|
||||
@@ -168,6 +175,9 @@ AT_CLEANUP
|
||||
## Variants. ##
|
||||
## ---------- ##
|
||||
|
||||
# Check that the variants are properly supported, including in error
|
||||
# recovery.
|
||||
|
||||
# AT_TEST([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>
|
||||
inline
|
||||
std::string
|
||||
string_cast (const T& t)
|
||||
to_string (const T& t)
|
||||
{
|
||||
std::ostringstream o;
|
||||
o << t;
|
||||
@@ -236,15 +246,18 @@ typedef std::list<std::string> strings_type;
|
||||
%token <::std::string> TEXT;
|
||||
%token <int> NUMBER;
|
||||
%token END_OF_FILE 0;
|
||||
%token COMMA ","
|
||||
|
||||
%type <::std::string> item;
|
||||
// Using the template type to exercize its parsing.
|
||||
// Starting with :: to ensure we don't output "<::" which starts by the
|
||||
// digraph for the left square bracket.
|
||||
%type <::std::list<std::string>> list result;
|
||||
%type <::std::list<std::string>> list;
|
||||
|
||||
%printer { yyo << $$; }
|
||||
<int> <::std::string> <::std::list<std::string>>;
|
||||
%destructor { std::cerr << "Destroy: " << $$ << '\n'; } <*>;
|
||||
%destructor { std::cerr << "Destroy: \"" << $$ << "\"\n"; } <::std::string>;
|
||||
%%
|
||||
|
||||
result:
|
||||
@@ -252,14 +265,14 @@ result:
|
||||
;
|
||||
|
||||
list:
|
||||
/* nothing */ { /* Generates an empty string list */ }
|
||||
| list item { std::swap ($$,$][1); $$.push_back ($][2); }
|
||||
| list error { std::swap ($$,$][1); }
|
||||
item { $$.push_back ($][1); }
|
||||
| list "," item { std::swap ($$, $][1); $$.push_back ($][3); }
|
||||
| list error { std::swap ($$, $][1); }
|
||||
;
|
||||
|
||||
item:
|
||||
TEXT { std::swap ($$,$][1); }
|
||||
| NUMBER { if ($][1 == 3) YYERROR; else $$ = string_cast ($][1); }
|
||||
TEXT { std::swap ($$, $][1); }
|
||||
| NUMBER { if ($][1 == 3) YYERROR; else $$ = to_string ($][1); }
|
||||
;
|
||||
%%
|
||||
]AT_TOKEN_CTOR_IF([],
|
||||
@@ -278,30 +291,43 @@ namespace yy
|
||||
parser::location_type* yylloc])[)]])[
|
||||
{]AT_LOCATION_IF([
|
||||
typedef parser::location_type location;])[
|
||||
static int stage = -1;
|
||||
++stage;
|
||||
if (stage == STAGE_MAX)
|
||||
{]AT_TOKEN_CTOR_IF([[
|
||||
// The 5 is a syntax error whose recovery requires that we discard
|
||||
// the lookahead. This tests a regression, see
|
||||
// <http://savannah.gnu.org/support/?108481>.
|
||||
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 ()])[);]],
|
||||
[AT_LOCATION_IF([
|
||||
*yylloc = location ();])[
|
||||
return parser::token::END_OF_FILE;]])[
|
||||
}
|
||||
else if (stage % 2)
|
||||
{]AT_TOKEN_CTOR_IF([[
|
||||
return parser::make_NUMBER (stage]AT_LOCATION_IF([, location ()])[);]],
|
||||
[[
|
||||
yylval->BUILD (int, stage);]AT_LOCATION_IF([
|
||||
|
||||
case ',':
|
||||
]AT_TOKEN_CTOR_IF([[
|
||||
return parser::make_COMMA (]AT_LOCATION_IF([location ()])[);]], [[
|
||||
]AT_LOCATION_IF([
|
||||
*yylloc = location ();])[
|
||||
return parser::token::NUMBER;]])[
|
||||
}
|
||||
else
|
||||
{]AT_TOKEN_CTOR_IF([[
|
||||
return parser::make_TEXT (string_cast (stage)]AT_LOCATION_IF([, location ()])[);]], [[
|
||||
yylval->BUILD (std::string, string_cast (stage));]AT_LOCATION_IF([
|
||||
*yylloc = location ();])[
|
||||
return parser::token::TEXT;]])[
|
||||
}
|
||||
return parser::token::COMMA;]])[
|
||||
|
||||
default:
|
||||
stage = stage - '0';
|
||||
if (stage % 2)
|
||||
{]AT_TOKEN_CTOR_IF([[
|
||||
return parser::make_NUMBER (stage]AT_LOCATION_IF([, location ()])[);]], [[
|
||||
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 ();
|
||||
}
|
||||
}
|
||||
@@ -312,8 +338,31 @@ namespace yy
|
||||
|
||||
AT_FULL_COMPILE([list])
|
||||
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_CLEANUP
|
||||
@@ -321,11 +370,11 @@ AT_CLEANUP
|
||||
|
||||
AT_TEST([[%skeleton "lalr1.cc" ]])
|
||||
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 %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" %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])
|
||||
|
||||
@@ -345,6 +394,7 @@ AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
|
||||
AT_DATA([input.yy],
|
||||
[[%skeleton "lalr1.cc"
|
||||
%locations
|
||||
%defines
|
||||
%debug
|
||||
%%
|
||||
exp: /* empty */;
|
||||
@@ -352,7 +402,7 @@ exp: /* empty */;
|
||||
]AT_YYERROR_DEFINE[
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-o input.cc input.yy], 0)
|
||||
AT_BISON_CHECK([-o input.cc input.yy])
|
||||
|
||||
AT_DATA([Doxyfile],
|
||||
[# 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.
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_BISON_OPTION_PUSHDEFS([%language "C++" %define api.namespace {$1}])
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
AT_DATA_GRAMMAR([[input.yy]],
|
||||
[[%language "C++"
|
||||
%define api.namespace {]$1[}
|
||||
%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],
|
||||
[AT_COMPILE_CXX([[input]], [[input.cc]])
|
||||
[AT_COMPILE_CXX([[input]])
|
||||
AT_PARSER_CHECK([[./input]])])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
])
|
||||
@@ -502,7 +552,7 @@ AT_SETUP([[Syntax error discarding no lookahead]])
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
|
||||
|
||||
AT_DATA_GRAMMAR([[input.yy]],
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
[[%skeleton "lalr1.cc"
|
||||
|
||||
%code {
|
||||
@@ -555,8 +605,7 @@ yy::parser::error (const std::string &m)
|
||||
]AT_MAIN_DEFINE[
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[-o input.cc input.yy]])
|
||||
AT_COMPILE_CXX([[input]])
|
||||
AT_FULL_COMPILE([[input]])
|
||||
# This used to print "Discarding 'a'." again at the end.
|
||||
AT_PARSER_CHECK([[./input]], [[1]], [[]],
|
||||
[[syntax error
|
||||
@@ -576,7 +625,7 @@ AT_SETUP([[Syntax error as exception]])
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
|
||||
|
||||
AT_DATA_GRAMMAR([[input.yy]],
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
[[%skeleton "lalr1.cc"
|
||||
|
||||
%code
|
||||
@@ -631,8 +680,7 @@ yy::parser::error (const std::string &m)
|
||||
]AT_MAIN_DEFINE[
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[-o input.cc input.yy]])
|
||||
AT_COMPILE_CXX([[input]])
|
||||
AT_FULL_COMPILE([[input]])
|
||||
|
||||
AT_PARSER_CHECK([[./input]], [[0]], [[]],
|
||||
[[error: invalid expression
|
||||
@@ -803,10 +851,10 @@ list:
|
||||
|
||||
item:
|
||||
'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
|
||||
// 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; }
|
||||
| 'p' { $$ = $][1; }
|
||||
| 's' { $$ = $][1; throw std::runtime_error ("reduction"); }
|
||||
@@ -929,9 +977,9 @@ AT_TEST([%define api.value.type variant], [without])
|
||||
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
## ------------------------------------ ##
|
||||
## C++ GLR parser identifier shadowing ##
|
||||
## ------------------------------------ ##
|
||||
## ------------------------------------- ##
|
||||
## 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&)
|
||||
{}
|
||||
|
||||
int main()
|
||||
int main ()
|
||||
{}
|
||||
])
|
||||
|
||||
|
||||
@@ -393,10 +393,10 @@ AT_CLEANUP
|
||||
## parse.error=verbose and consistent errors. ##
|
||||
## ------------------------------------------- ##
|
||||
|
||||
AT_SETUP([[parse.error=verbose and consistent errors]])
|
||||
|
||||
m4_pushdef([AT_CONSISTENT_ERRORS_CHECK], [
|
||||
|
||||
AT_SETUP([[parse.error=verbose and consistent errors: $1]])
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS([$1])
|
||||
|
||||
m4_pushdef([AT_YYLEX_PROTOTYPE],
|
||||
@@ -483,7 +483,11 @@ m4_popdef([AT_EXPECTING])
|
||||
m4_popdef([AT_YYLEX_PROTOTYPE])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
|
||||
])
|
||||
AT_CLEANUP
|
||||
]) dnl AT_CONSISTENT_ERRORS_CHECK
|
||||
|
||||
|
||||
|
||||
|
||||
m4_pushdef([AT_PREVIOUS_STATE_GRAMMAR],
|
||||
[[%nonassoc 'a';
|
||||
@@ -653,7 +657,6 @@ m4_popdef([AT_USER_ACTION_INPUT])
|
||||
|
||||
m4_popdef([AT_CONSISTENT_ERRORS_CHECK])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user