[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
About %destructor is c++ mode
From: |
Min Wang |
Subject: |
About %destructor is c++ mode |
Date: |
Wed, 17 Aug 2016 19:20:34 -0400 |
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
- About %destructor is c++ mode,
Min Wang <=
- Re: About %destructor is c++ mode, Hans Åberg, 2016/08/18
- Re: About %destructor is c++ mode, Min Wang, 2016/08/18
- Re: About %destructor is c++ mode, Hans Åberg, 2016/08/18
- Re: About %destructor is c++ mode, Min Wang, 2016/08/18
- Re: About %destructor is c++ mode, Hans Åberg, 2016/08/18
- Re: About %destructor is c++ mode, Min Wang, 2016/08/18
- Re: About %destructor is c++ mode, Hans Åberg, 2016/08/18
- Re: About %destructor is c++ mode, Min Wang, 2016/08/18
- Re: About %destructor is c++ mode, Hans Åberg, 2016/08/18
- Re: About %destructor is c++ mode, Min Wang, 2016/08/18