mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-18 00:33:03 +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
|
** 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
|
||||||
|
|
||||||
|
|||||||
@@ -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
6
THANKS
@@ -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
|
||||||
|
|||||||
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.
|
/// (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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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_;])[
|
||||||
};
|
};
|
||||||
]])
|
]])
|
||||||
|
|
||||||
|
|||||||
@@ -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 ()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
140
tests/c++.at
140
tests/c++.at
@@ -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 ()
|
||||||
{}
|
{}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user