diff options
author | Akim Demaille <akim@lrde.epita.fr> | 2015-01-08 10:19:10 +0100 |
---|---|---|
committer | Akim Demaille <akim@lrde.epita.fr> | 2015-01-08 16:07:59 +0100 |
commit | ee2f433512c2bfc1f8fe0f518f0e80e5e540bf26 (patch) | |
tree | 5a5ffcbed716a24c92b3ccdfa963c319642ccd92 | |
parent | 5422471cbb68d8b5775046702cc92209b0718f58 (diff) | |
download | bison-ee2f433512c2bfc1f8fe0f518f0e80e5e540bf26.tar.gz |
c++: provide a means to clear symbols
The symbol destructor is currently the only means to clear a symbol.
Unfortunately during error recovery we might have to clear the
lookahead, which is a local variable (yyla) that has not yet reached
its end of scope.
Rather that duplicating the code to destroy a symbol, or rather than
destroying and recreating yyla, let's provide a means to clear a
symbol.
Reported by Antonio Silva Correia, with an analysis from Michel d'Hooge.
<http://savannah.gnu.org/support/?108481>
* data/c++.m4, data/lalr1.cc (basis_symbol::clear, by_state::clear)
(by_type::clear): New.
(basic_symbol::~basic_symbol): Use clear.
-rw-r--r-- | THANKS | 2 | ||||
-rw-r--r-- | data/c++.m4 | 24 | ||||
-rw-r--r-- | data/lalr1.cc | 12 |
3 files changed, 36 insertions, 2 deletions
@@ -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 @@ -85,6 +86,7 @@ Matt Rosing rosing@peakfive.com 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 diff --git a/data/c++.m4 b/data/c++.m4 index f9ea7e9d..8494d214 100644 --- a/data/c++.m4 +++ b/data/c++.m4 @@ -215,6 +215,9 @@ m4_define([b4_public_types_declare], /// Destroy the symbol. ~basic_symbol (); + /// Destroy contents, and record that is empty. + void clear (); + /// Whether empty. bool empty () const; @@ -247,6 +250,9 @@ 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); @@ -329,6 +335,14 @@ 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 (); @@ -341,6 +355,7 @@ m4_define([b4_public_types_define], // Type destructor. ]b4_symbol_variant([[yytype]], [[value]], [[template destroy]])])[ + Base::clear (); } template <typename Base> @@ -381,10 +396,17 @@ m4_define([b4_public_types_define], 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_symbol; + that.clear (); } inline diff --git a/data/lalr1.cc b/data/lalr1.cc index 1c3481ff..9ab9421e 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -288,6 +288,9 @@ 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); @@ -544,10 +547,17 @@ m4_if(b4_prefix, [yy], [], 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_state; + that.clear (); } inline |