mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-11 04:02:52 -06:00
fix space leaks from the LR table maker
This commit is contained in:
@@ -10,7 +10,7 @@
|
|||||||
struct PgfLRTableMaker::State {
|
struct PgfLRTableMaker::State {
|
||||||
size_t id;
|
size_t id;
|
||||||
Predictions *preds;
|
Predictions *preds;
|
||||||
std::vector<Item*> seed;
|
std::vector<Item*> items;
|
||||||
std::vector<PgfLRShift> shifts;
|
std::vector<PgfLRShift> shifts;
|
||||||
std::vector<PgfLRReduce> reductions;
|
std::vector<PgfLRReduce> reductions;
|
||||||
|
|
||||||
@@ -21,7 +21,6 @@ struct PgfLRTableMaker::State {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PgfLRTableMaker::Item {
|
struct PgfLRTableMaker::Item {
|
||||||
Item *next;
|
|
||||||
object lin_obj;
|
object lin_obj;
|
||||||
size_t seq_index;
|
size_t seq_index;
|
||||||
ref<PgfSequence> seq;
|
ref<PgfSequence> seq;
|
||||||
@@ -32,7 +31,13 @@ struct PgfLRTableMaker::Predictions {
|
|||||||
ref<PgfConcrLincat> lincat;
|
ref<PgfConcrLincat> lincat;
|
||||||
size_t r;
|
size_t r;
|
||||||
bool is_epsilon;
|
bool is_epsilon;
|
||||||
Item *items;
|
std::vector<Item*> items;
|
||||||
|
|
||||||
|
~Predictions() {
|
||||||
|
for (Item *item : items) {
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PgfLRTableMaker::CompareItem : std::less<Item*> {
|
struct PgfLRTableMaker::CompareItem : std::less<Item*> {
|
||||||
@@ -51,6 +56,8 @@ struct PgfLRTableMaker::CompareItem : std::less<Item*> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const PgfLRTableMaker::CompareItem PgfLRTableMaker::compare_item;
|
||||||
|
|
||||||
PgfLRTableMaker::PgfLRTableMaker(ref<PgfAbstr> abstr, ref<PgfConcr> concr)
|
PgfLRTableMaker::PgfLRTableMaker(ref<PgfAbstr> abstr, ref<PgfConcr> concr)
|
||||||
{
|
{
|
||||||
this->abstr = abstr;
|
this->abstr = abstr;
|
||||||
@@ -83,7 +90,6 @@ PgfLRTableMaker::PgfLRTableMaker(ref<PgfAbstr> abstr, ref<PgfConcr> concr)
|
|||||||
lincat->n_lindefs*lincat->fields->len + i-lincat->n_lindefs;
|
lincat->n_lindefs*lincat->fields->len + i-lincat->n_lindefs;
|
||||||
ref<PgfSequence> seq = *vector_elem(lincat->seqs, seq_index);
|
ref<PgfSequence> seq = *vector_elem(lincat->seqs, seq_index);
|
||||||
Item *item = new Item;
|
Item *item = new Item;
|
||||||
item->next = NULL;
|
|
||||||
item->lin_obj = lincat.tagged();
|
item->lin_obj = lincat.tagged();
|
||||||
item->seq_index = seq_index;
|
item->seq_index = seq_index;
|
||||||
item->seq = seq;
|
item->seq = seq;
|
||||||
@@ -93,7 +99,7 @@ PgfLRTableMaker::PgfLRTableMaker(ref<PgfAbstr> abstr, ref<PgfConcr> concr)
|
|||||||
ctxt.update(item->seq_index);
|
ctxt.update(item->seq_index);
|
||||||
ctxt.update(item->dot);
|
ctxt.update(item->dot);
|
||||||
|
|
||||||
state->seed.push_back(item);
|
state->items.push_back(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
MD5Digest digest;
|
MD5Digest digest;
|
||||||
@@ -104,6 +110,19 @@ PgfLRTableMaker::PgfLRTableMaker(ref<PgfAbstr> abstr, ref<PgfConcr> concr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->reductions = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PgfLRTableMaker::~PgfLRTableMaker()
|
||||||
|
{
|
||||||
|
for (auto p : states) {
|
||||||
|
delete p.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto p : predictions) {
|
||||||
|
delete p.second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG_STATE_CREATION) || defined(DEBUG_AUTOMATON)
|
#if defined(DEBUG_STATE_CREATION) || defined(DEBUG_AUTOMATON)
|
||||||
@@ -257,11 +276,10 @@ void PgfLRTableMaker::predict(Item *item, ref<PgfText> cat, size_t r)
|
|||||||
Predictions *&preds = predictions[Key(cat,r)];
|
Predictions *&preds = predictions[Key(cat,r)];
|
||||||
Predictions *tmp_preds = preds;
|
Predictions *tmp_preds = preds;
|
||||||
if (preds == NULL) {
|
if (preds == NULL) {
|
||||||
preds = new Predictions();
|
preds = new Predictions;
|
||||||
preds->lincat = 0;
|
preds->lincat = 0;
|
||||||
preds->r = r;
|
preds->r = r;
|
||||||
preds->is_epsilon = false;
|
preds->is_epsilon = false;
|
||||||
preds->items = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
State *&next_state = continuations[preds];
|
State *&next_state = continuations[preds];
|
||||||
@@ -269,14 +287,13 @@ void PgfLRTableMaker::predict(Item *item, ref<PgfText> cat, size_t r)
|
|||||||
if (next_state == NULL) {
|
if (next_state == NULL) {
|
||||||
next_state = new State(preds);
|
next_state = new State(preds);
|
||||||
}
|
}
|
||||||
Item *next_item = new Item();
|
Item *next_item = new Item;
|
||||||
next_item->next = NULL;
|
|
||||||
next_item->lin_obj = item->lin_obj;
|
next_item->lin_obj = item->lin_obj;
|
||||||
next_item->seq_index = item->seq_index;
|
next_item->seq_index = item->seq_index;
|
||||||
next_item->seq = item->seq;
|
next_item->seq = item->seq;
|
||||||
next_item->dot = item->dot+1;
|
next_item->dot = item->dot+1;
|
||||||
next_state->seed.push_back(next_item);
|
next_state->items.push_back(next_item);
|
||||||
push_heap(next_state->seed.begin(), next_state->seed.end(), compare_item);
|
push_heap(next_state->items.begin(), next_state->items.end(), compare_item);
|
||||||
|
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
if (tmp_preds == NULL) {
|
if (tmp_preds == NULL) {
|
||||||
@@ -287,10 +304,8 @@ void PgfLRTableMaker::predict(Item *item, ref<PgfText> cat, size_t r)
|
|||||||
};
|
};
|
||||||
probspace_iter(abstr->funs_by_cat, cat, f, false);
|
probspace_iter(abstr->funs_by_cat, cat, f, false);
|
||||||
} else {
|
} else {
|
||||||
Item *new_item = preds->items;
|
for (Item *new_item : preds->items) {
|
||||||
while (new_item != NULL) {
|
|
||||||
process(new_item);
|
process(new_item);
|
||||||
new_item = new_item->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,12 +329,11 @@ void PgfLRTableMaker::predict(ref<PgfAbsFun> absfun, Predictions *preds)
|
|||||||
preds->is_epsilon = true;
|
preds->is_epsilon = true;
|
||||||
} else {
|
} else {
|
||||||
Item *item = new Item;
|
Item *item = new Item;
|
||||||
item->next = preds->items;
|
|
||||||
item->lin_obj = lin.tagged();
|
item->lin_obj = lin.tagged();
|
||||||
item->seq_index = seq_index;
|
item->seq_index = seq_index;
|
||||||
item->seq = seq;
|
item->seq = seq;
|
||||||
item->dot = 0;
|
item->dot = 0;
|
||||||
preds->items = item;
|
preds->items.push_back(item);
|
||||||
process(item);
|
process(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,7 +342,26 @@ void PgfLRTableMaker::predict(ref<PgfAbsFun> absfun, Predictions *preds)
|
|||||||
|
|
||||||
void PgfLRTableMaker::complete(Item *item)
|
void PgfLRTableMaker::complete(Item *item)
|
||||||
{
|
{
|
||||||
completed.push_back(item);
|
PgfLRReduce red;
|
||||||
|
red.lin_obj = item->lin_obj;
|
||||||
|
red.seq_index = item->seq_index;
|
||||||
|
reductions->push_back(red);
|
||||||
|
#if defined(DEBUG_AUTOMATON)
|
||||||
|
switch (ref<PgfConcrLin>::get_tag(red.lin_obj)) {
|
||||||
|
case PgfConcrLin::tag: {
|
||||||
|
auto lin =
|
||||||
|
ref<PgfConcrLin>::untagged(red.lin_obj);
|
||||||
|
fprintf(stderr, "reduce %s/%zu\n", lin->name.text, red.seq_index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PgfConcrLincat::tag: {
|
||||||
|
auto lincat =
|
||||||
|
ref<PgfConcrLincat>::untagged(red.lin_obj);
|
||||||
|
fprintf(stderr, "reduce linref %s/%zu\n", lincat->name.text, red.seq_index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<PgfLRTable> PgfLRTableMaker::make()
|
ref<PgfLRTable> PgfLRTableMaker::make()
|
||||||
@@ -341,24 +374,26 @@ ref<PgfLRTable> PgfLRTableMaker::make()
|
|||||||
fprintf(stderr, "--------------- state %ld ---------------\n", state->id);
|
fprintf(stderr, "--------------- state %ld ---------------\n", state->id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (!state->seed.empty()) {
|
reductions = &state->reductions;
|
||||||
Item *item = state->seed.back(); state->seed.pop_back();
|
while (!state->items.empty()) {
|
||||||
|
Item *item = state->items.back(); state->items.pop_back();
|
||||||
|
|
||||||
#if defined(DEBUG_AUTOMATON) && !defined(DEBUG_STATE_CREATION)
|
#if defined(DEBUG_AUTOMATON) && !defined(DEBUG_STATE_CREATION)
|
||||||
// The order in which we process the items should not matter,
|
// The order in which we process the items should not matter,
|
||||||
// For debugging however it is useful to see them in the same order.
|
// For debugging however it is useful to see them in the same order.
|
||||||
pop_heap(state->seed.begin(),state->seed.end(),compare_item);
|
pop_heap(state->items.begin(),state->items.end(),compare_item);
|
||||||
print_item(item);
|
print_item(item);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
process(item);
|
process(item);
|
||||||
|
delete item;
|
||||||
}
|
}
|
||||||
state->seed.shrink_to_fit();
|
state->items.shrink_to_fit();
|
||||||
|
|
||||||
for (auto i : continuations) {
|
for (auto i : continuations) {
|
||||||
MD5Context ctxt;
|
MD5Context ctxt;
|
||||||
auto begin = i.second->seed.begin();
|
auto begin = i.second->items.begin();
|
||||||
auto end = i.second->seed.end();
|
auto end = i.second->items.end();
|
||||||
while (begin != end) {
|
while (begin != end) {
|
||||||
Item *item = *(--end);
|
Item *item = *(--end);
|
||||||
ctxt.update(item->lin_obj);
|
ctxt.update(item->lin_obj);
|
||||||
@@ -378,6 +413,7 @@ ref<PgfLRTable> PgfLRTableMaker::make()
|
|||||||
todo.push_back(next_state);
|
todo.push_back(next_state);
|
||||||
} else {
|
} else {
|
||||||
delete i.second;
|
delete i.second;
|
||||||
|
i.second = next_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfLRShift shift;
|
PgfLRShift shift;
|
||||||
@@ -394,30 +430,6 @@ ref<PgfLRTable> PgfLRTableMaker::make()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
continuations.clear();
|
continuations.clear();
|
||||||
|
|
||||||
for (Item *item : completed) {
|
|
||||||
PgfLRReduce red;
|
|
||||||
red.lin_obj = item->lin_obj;
|
|
||||||
red.seq_index = item->seq_index;
|
|
||||||
state->reductions.push_back(red);
|
|
||||||
#if defined(DEBUG_AUTOMATON)
|
|
||||||
switch (ref<PgfConcrLin>::get_tag(red.lin_obj)) {
|
|
||||||
case PgfConcrLin::tag: {
|
|
||||||
auto lin =
|
|
||||||
ref<PgfConcrLin>::untagged(red.lin_obj);
|
|
||||||
fprintf(stderr, "reduce %s/%zu\n", lin->name.text, red.seq_index);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PgfConcrLincat::tag: {
|
|
||||||
auto lincat =
|
|
||||||
ref<PgfConcrLincat>::untagged(red.lin_obj);
|
|
||||||
fprintf(stderr, "reduce linref %s/%zu\n", lincat->name.text, red.seq_index);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
completed.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<PgfLRTable> lrtable = vector_new<PgfLRState>(states.size());
|
ref<PgfLRTable> lrtable = vector_new<PgfLRState>(states.size());
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class PGF_INTERNAL_DECL PgfLRTableMaker
|
|||||||
std::map<MD5Digest,State*> states;
|
std::map<MD5Digest,State*> states;
|
||||||
std::map<Key,Predictions*,CompareKey> predictions;
|
std::map<Key,Predictions*,CompareKey> predictions;
|
||||||
std::map<Predictions*,State*> continuations;
|
std::map<Predictions*,State*> continuations;
|
||||||
std::vector<Item*> completed;
|
std::vector<PgfLRReduce> *reductions;
|
||||||
|
|
||||||
void process(Item *item);
|
void process(Item *item);
|
||||||
void symbol(Item *item, PgfSymbol sym);
|
void symbol(Item *item, PgfSymbol sym);
|
||||||
@@ -48,6 +48,7 @@ class PGF_INTERNAL_DECL PgfLRTableMaker
|
|||||||
public:
|
public:
|
||||||
PgfLRTableMaker(ref<PgfAbstr> abstr, ref<PgfConcr> concr);
|
PgfLRTableMaker(ref<PgfAbstr> abstr, ref<PgfConcr> concr);
|
||||||
ref<PgfLRTable> make();
|
ref<PgfLRTable> make();
|
||||||
|
~PgfLRTableMaker();
|
||||||
};
|
};
|
||||||
|
|
||||||
class PgfPrinter;
|
class PgfPrinter;
|
||||||
|
|||||||
Reference in New Issue
Block a user