forked from GitHub/gf-core
fix memory leaks in the parser.cxx
This commit is contained in:
@@ -1207,6 +1207,8 @@ struct PgfParser::Choice {
|
||||
Choice(int fid) {
|
||||
this->fid = fid;
|
||||
}
|
||||
|
||||
~Choice();
|
||||
};
|
||||
|
||||
struct PgfParser::Production {
|
||||
@@ -1262,6 +1264,12 @@ struct PgfParser::Stage {
|
||||
start = spot;
|
||||
end = spot;
|
||||
}
|
||||
|
||||
~Stage() {
|
||||
for (StackNode *node : nodes) {
|
||||
delete node;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct PgfParser::ExprState {
|
||||
@@ -1283,6 +1291,17 @@ struct PgfParser::ExprInstance {
|
||||
}
|
||||
};
|
||||
|
||||
PgfParser::Choice::~Choice() {
|
||||
while (states.size() > 0) {
|
||||
ExprState *state = states.back(); states.pop_back();
|
||||
delete state;
|
||||
}
|
||||
|
||||
for (Production *prod : prods) {
|
||||
delete prod;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DEBUG_STATE_CREATION) || defined(DEBUG_AUTOMATON) || defined(DEBUG_PARSER)
|
||||
void PgfParser::print_prod(Choice *choice, Production *prod)
|
||||
{
|
||||
@@ -1379,6 +1398,7 @@ void PgfParser::shift(StackNode *parent, ref<PgfConcrLincat> lincat, size_t r, P
|
||||
if (node == NULL) {
|
||||
node = new StackNode(before, shift->next_state);
|
||||
node->choice = new Choice(++last_fid);
|
||||
dynamic.push_back(node->choice);
|
||||
after->nodes.push_back(node);
|
||||
}
|
||||
|
||||
@@ -1485,6 +1505,7 @@ PgfParser::Choice *PgfParser::intersect_choice(Choice *choice1, Choice *choice2,
|
||||
}
|
||||
|
||||
Choice *choice = new Choice(++last_fid);
|
||||
dynamic.push_back(choice);
|
||||
im[key] = choice;
|
||||
for (Production *prod1 : choice1->prods) {
|
||||
for (Production *prod2 : choice2->prods) {
|
||||
@@ -1704,6 +1725,7 @@ void PgfParser::predict_expr_states(Choice *choice, prob_t outside_prob)
|
||||
state->n_args = 0;
|
||||
state->expr = u->efun(&prod->lin->name);
|
||||
state->prob = outside_prob+prod->lin->absfun->prob;
|
||||
exprs.push_back(state->expr);
|
||||
queue.push(state);
|
||||
}
|
||||
}
|
||||
@@ -1768,7 +1790,7 @@ bool PgfParser::process_expr_state(ExprState *state)
|
||||
if (choice == NULL) {
|
||||
PgfExpr meta = u->emeta(0);
|
||||
PgfExpr app = u->eapp(state->expr, meta);
|
||||
u->free_ref(state->expr);
|
||||
exprs.push_back(app);
|
||||
u->free_ref(meta);
|
||||
state->expr = app;
|
||||
state->n_args++;
|
||||
@@ -1808,6 +1830,7 @@ void PgfParser::complete_expr_state(ExprState *state)
|
||||
void PgfParser::combine_expr_state(ExprState *state, ExprInstance &inst)
|
||||
{
|
||||
PgfExpr app = u->eapp(state->expr, inst.expr);
|
||||
exprs.push_back(app);
|
||||
|
||||
ExprState *app_state = new ExprState();
|
||||
app_state->prob = state->prob + inst.prob;
|
||||
@@ -1818,11 +1841,6 @@ void PgfParser::combine_expr_state(ExprState *state, ExprInstance &inst)
|
||||
queue.push(app_state);
|
||||
}
|
||||
|
||||
void PgfParser::release_expr_state(ExprState *state)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PgfExpr PgfParser::fetch(PgfDB *db, prob_t *prob)
|
||||
{
|
||||
DB_scope scope(db, READER_SCOPE);
|
||||
@@ -1846,9 +1864,42 @@ PgfExpr PgfParser::fetch(PgfDB *db, prob_t *prob)
|
||||
#endif
|
||||
|
||||
if (process_expr_state(state)) {
|
||||
release_expr_state(state);
|
||||
delete state;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PgfParser::~PgfParser()
|
||||
{
|
||||
while (before != NULL) {
|
||||
Stage *tmp = before;
|
||||
before = before->next;
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
while (ahead != NULL) {
|
||||
Stage *tmp = ahead;
|
||||
ahead = ahead->next;
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
for (auto it : persistant) {
|
||||
delete it.second;
|
||||
}
|
||||
|
||||
for (Choice *choice : dynamic) {
|
||||
delete choice;
|
||||
}
|
||||
|
||||
for (PgfExpr expr : exprs) {
|
||||
u->free_ref(expr);
|
||||
}
|
||||
|
||||
std::priority_queue<ExprState*, std::vector<ExprState*>, CompareExprState> queue;
|
||||
while (!queue.empty()) {
|
||||
ExprState *state = queue.top(); queue.pop();
|
||||
delete state;
|
||||
}
|
||||
}
|
||||
@@ -119,8 +119,11 @@ class PGF_INTERNAL_DECL PgfParser : public PgfPhraseScanner, public PgfExprEnum
|
||||
std::priority_queue<ExprState*, std::vector<ExprState*>, CompareExprState> queue;
|
||||
int last_fid;
|
||||
|
||||
std::vector<Choice*> dynamic;
|
||||
std::map<object,Choice*> persistant;
|
||||
|
||||
std::vector<PgfExpr> exprs;
|
||||
|
||||
Choice *top_choice;
|
||||
size_t top_choice_index;
|
||||
|
||||
@@ -150,10 +153,10 @@ class PGF_INTERNAL_DECL PgfParser : public PgfPhraseScanner, public PgfExprEnum
|
||||
bool process_expr_state(ExprState *state);
|
||||
void complete_expr_state(ExprState *state);
|
||||
void combine_expr_state(ExprState *state, ExprInstance &inst);
|
||||
void release_expr_state(ExprState *state);
|
||||
|
||||
public:
|
||||
PgfParser(ref<PgfConcr> concr, ref<PgfConcrLincat> start, PgfText *sentence, bool case_sensitive, PgfMarshaller *m, PgfUnmarshaller *u);
|
||||
~PgfParser();
|
||||
|
||||
virtual void space(PgfTextSpot *start, PgfTextSpot *end, PgfExn* err);
|
||||
virtual void start_matches(PgfTextSpot *end, PgfExn* err);
|
||||
|
||||
Reference in New Issue
Block a user