HI I guess I have some confusions/misunderstanding on how to use %destructor in bision 3.0.4
(1) https://www.gnu.org/software/bison/manual/html_node/Calc_002b_002b-Parser.html#Calc_002b_002b-Parser said: No %destructor is needed to enable memory deallocation during error recovery; the memory, for strings for instance, will be reclaimed by the regular destructor. so if I have something like that ( pointer) in as token type: %type <PROG*> PROG %type <ListExp*> ListExp My thinking about using PROG* instead of PROG is because I do not want to copy constructor a big PROG, is it correct? In this case of pointer, do I need to have a %destructor? %destructor { delete $$; } PROG %destructor { delete $$; } ListExp (2) when %destructor is called? Assuming I need those %destructor, it seems that %destructor was called even for a every successful parse. I thought it should only called during During error recovery. e.g: some C++ code: using Exp_PTR = std::unique_ptr<Exp>; class Elor : public Exp { public: Exp_PTR exp_1; Exp_PTR exp_2; // use unique_ptr to take the ownership of the raw pointer from bison Elor(Exp *p1, Exp *p2): exp_1( p1 ), exp_2 ( p2 ) {} ~Elor() {} } // real one here using ListExp_PTR = std::unique_ptr<ListExp>; class Json_Filter : public PROG { public: ListExp_PTR listexp_; Json_Filter(ListExp *p1) : listexp_( p1 ) {} ~Json_Filter() {} } class ListExp : public Visitable, public std::vector<Exp_PTR> { }; bison.yy file: %define api.value.type variant %define api.token.constructor ... %type <PROG*> PROG %type <ListExp*> ListExp %type <Exp*> Exp %type <Exp*> Exp1 ... %destructor { std::cout << " I am PROG \n " << $$; /*delete $$;*/ } PROG %destructor { std::cout << " I am listexp \n" << $$; /* delete $$; */ } ListExp %start PROG; PROG : ListExp { std::reverse( $1->begin(), $1->end() ); // store the result to filter_driver.prog driver.store_ast( new Json_Filter($1) ); } ; ListExp : Exp { $$ = new ListExp(); $$->push_back( std::move(Exp_PTR($1)) ); } | Exp _SYMB_SEMICOLON ListExp { $3->push_back( std::move(Exp_PTR($1)) ); $$ = $3 ; } | /* empty */ { $$ = new ListExp(); } ; Exp : Exp _SYMB_OR Exp1 { $$ = new Elor($1, $3) ; } | Exp1 { $$ = $1; } ; ... so if I comment out the destrcutor: /* delete $$ */, I can ran the parser OK, and it can been seen that even for a successful paring, theose %destrcutor are called. If I uncomment out the delete $$, I will get the segment fault, why? I thought it should only called during During error recovery not for the successful parsing. Thanks min _______________________________________________ help-bison@gnu.org https://lists.gnu.org/mailman/listinfo/help-bison