From ee2f433512c2bfc1f8fe0f518f0e80e5e540bf26 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 8 Jan 2015 10:19:10 +0100 Subject: [PATCH] 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. * data/c++.m4, data/lalr1.cc (basis_symbol::clear, by_state::clear) (by_type::clear): New. (basic_symbol::~basic_symbol): Use clear. --- THANKS | 2 ++ data/c++.m4 | 24 +++++++++++++++++++++++- data/lalr1.cc | 12 +++++++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/THANKS b/THANKS index 908498c7..98ec269d 100644 --- a/THANKS +++ b/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 @@ -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 inline ]b4_parser_class_name[::basic_symbol::~basic_symbol () + { + clear (); + } + + template + inline + void + ]b4_parser_class_name[::basic_symbol::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 @@ -379,12 +394,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_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); @@ -542,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_state; + that.clear (); } inline -- 2.47.2