HI Also
http://lists.gnu.org/archive/html/bug-bison/2015-01/msg00066.html seems indicated bison does not support std::unique_ptr as a semantic values min On Thu, Aug 18, 2016 at 3:05 PM, Min Wang <[email protected]> wrote: > HI > @kaz. thanks. I will check the %union later > > I'like to use the smart pointers ( std::unique_ptr) , but somehow I got > some compiler errors. > > here are some details: > e.g: > > using PROG_PTR = std::unique_ptr<PROG>; > .... > > > %type <PROG_PTR> PROG > > %type <ListExp_PTR> ListExp > > %type <Exp_PTR> Exp > > ... > > > PROG : ListExp { > std::reverse( $1->begin(), $1->end() ); > // store the result to filter_driver.prog > driver.store_ast( new Json_Filter( std::move($1) ) ); > } > ; > > ListExp : Exp { > ListExp_PTR tmp( new ListExp() ) ; > tmp->push_back( std::move($1) ); > std::swap( $$, tmp ); > } > > //some classes > > class PROG : public Visitable > > { > > public: > > virtual ~PROG() {}; > > > > }; > > // real one here > > using ListExp_PTR = std::unique_ptr<ListExp>; > > > > class Json_Filter : public PROG > > { > > public: > > ListExp_PTR listexp_; > > > > Json_Filter(ListExp_PTR p1) : listexp_( std::move(p1) ) {} > > ~Json_Filter() {} > > > > }; > > // should not inherit vector here, put here just for testing now. > class ListExp : public Visitable, public std::vector<Exp_PTR> > > { > > public: > > }; > > > > but I got those errors: > .... > > In file included from filter_parser.cpp:46:0: > > filter_parser.hh: In instantiation of ‘T& brc_filter::variant<S>::build(const > T&) [with T = std::unique_ptr<ListExp>; long unsigned int S = 8ul]’: > filter_parser.hh:241:12: required from ‘void > brc_filter::variant<S>::copy(const self_type&) [with T = > std::unique_ptr<ListExp>; long unsigned int S = 8ul; > brc_filter::variant<S>::self_type = brc_filter::variant<8ul>]’ > filter_parser.cpp:353:46: required from here > > filter_parser.hh:184:37: error: use of deleted function > ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) > [with _Tp = ListExp; _Dp = std::default_delete<ListExp>]’ > return *new (yyas_<T> ()) T (t); > > ^ > > In file included from /usr/include/c++/4.9/memory:81:0, > > from syntax.hh:6, > > from filter_parser.yy:46, > > from filter_parser.cpp:46: > > /usr/include/c++/4.9/bits/unique_ptr.h:356:7: note: declared here > > unique_ptr(const unique_ptr&) = delete; > > .... > > the filter_parser.hh:184 is: > > /// Instantiate a \a T in here from \a t. > > template <typename T> > > T& > > build (const T& t) > > { > > YYASSERT (!yytypeid_); > > YYASSERT (sizeof (T) <= S); > > yytypeid_ = & typeid (T); > > return *new (yyas_<T> ()) T (t); > > } > > > seems the build function somehow is not right? > > > thanks > > > min > > On Thu, Aug 18, 2016 at 1:12 PM, Kaz Kylheku <[email protected]> wrote: > >> On 18.08.2016 08:36, Min Wang wrote: >> >>> HI >>> >>> In bison 3.0.4, the %destructor seems to be called even in the normal >>> parse >>> >> >> In your example program you are using "Variants" rather >> than %union. That's a very special C++-specific Bison feature. >> >> It seems that there is no reason to use %destructor if you're >> using variants. If any of the variants are pointers, they can >> just be smart pointers; they don't have to be low level pointers. >> >> Can you confirm whether %destructor is still called in the >> normal parse if instead of: >> >> %type <PROG*> PROG >> %type <ListExp*> ListExp >> >> you use >> >> %union { >> PROG *PROG; >> ListExp *ListExp; >> } >> >> That is to say, is this a issue specific to variants, or does it >> affect C++ parsers regardless of whether %union or variants >> are used? >> >> If under %union, %destructor is correctly called only during >> error recovery (the issue is absent) then just use %union, >> since all your semantic value types are pointers. Then be sure >> you have all the right delete calls in your grammar actions. >> >> If you use variants, it seems you can side-step the issue >> by not using pointers. If the values are smart pointers, >> then there is no problem, because a rule like: >> >> foo : bar { $$ = $1; } >> >> will handle the transfer from $1 to $$ using the smart pointer >> assignment operator, allowing $1 to then be safely destroyed >> by its destructor. >> >> It does seem that you have discovered at least this bug, >> or deviation from documented behavior: when plain pointer types >> are used in variant declarations in a C++ parser, and %destructor >> is used to free them in all circumstances. >> >> So for instance, suppose that we use the type <char *>, >> and we have a %destructor which calls free. In a C parser, >> we might just have this: >> >> foo : bar { $$ = $1; } /* transfer ownership of pointer */ >> >> But under C++ Bison with variants, we must do: >> >> foo : bar { $$ = strdup($1); } /* $1 %destructor will kick in */ >> >> Or perhaps this will work: >> >> foo : bar { $$ = $1; >> $1 = NULL; } /* Spare $1 from jaws of %destructor */ >> >> >> >> > > > -- > http://www.comrite.com > > > > -- http://www.comrite.com
