Fixed a number of mem leaks in TokenStreamRewriter.

Also added a workaround for duplicate ATN state transitions. Looks there is a problem in the ATN generation by ANTLR which needs investigation.
This commit is contained in:
Mike Lischke 2016-11-16 13:27:58 +01:00
parent 8450599e75
commit af0ac9e2bb
2 changed files with 16 additions and 4 deletions

View File

@ -85,7 +85,8 @@ size_t TokenStreamRewriter::InsertBeforeOp::execute(std::string *buf) {
return index + 1;
}
TokenStreamRewriter::ReplaceOp::ReplaceOp(TokenStreamRewriter *outerInstance, size_t from, size_t to, const std::string& text) : RewriteOperation(outerInstance, from, text), outerInstance(outerInstance) {
TokenStreamRewriter::ReplaceOp::ReplaceOp(TokenStreamRewriter *outerInstance, size_t from, size_t to, const std::string& text)
: RewriteOperation(outerInstance, from, text), outerInstance(outerInstance) {
InitializeInstanceFields();
lastIndex = to;
@ -346,17 +347,19 @@ std::unordered_map<size_t, TokenStreamRewriter::RewriteOperation*> TokenStreamRe
}
ReplaceOp *rop = static_cast<ReplaceOp*>(op);
// Wipe prior inserts within range
InsertBeforeOp* type = nullptr;
std::vector<InsertBeforeOp*> inserts = getKindOfOps(rewrites, type, i);
InsertBeforeOp *type = nullptr;
std::vector<InsertBeforeOp *> inserts = getKindOfOps(rewrites, type, i);
for (auto iop : inserts) {
if (iop->index == rop->index) {
// E.g., insert before 2, delete 2..2; update replace
// text to include insert before, kill insert
delete rewrites[iop->instructionIndex];
rewrites[iop->instructionIndex] = nullptr;
rop->text = iop->text + (!rop->text.empty() ? rop->text : "");
}
else if (iop->index > rop->index && iop->index <= rop->lastIndex) {
// delete insert as it's a no-op.
delete rewrites[iop->instructionIndex];
rewrites[iop->instructionIndex] = nullptr;
}
}
@ -366,6 +369,7 @@ std::unordered_map<size_t, TokenStreamRewriter::RewriteOperation*> TokenStreamRe
for (auto prevRop : prevReplaces) {
if (prevRop->index >= rop->index && prevRop->lastIndex <= rop->lastIndex) {
// delete replace as it's a no-op.
delete rewrites[prevRop->instructionIndex];
rewrites[prevRop->instructionIndex] = nullptr;
continue;
}
@ -375,7 +379,7 @@ std::unordered_map<size_t, TokenStreamRewriter::RewriteOperation*> TokenStreamRe
// Delete special case of replace (text==null):
// D.i-j.u D.x-y.v | boundaries overlap combine to max(min)..max(right)
if (prevRop->text.empty() && rop->text.empty() && !disjoint) {
//System.out.println("overlapping deletes: "+prevRop+", "+rop);
delete rewrites[prevRop->instructionIndex];
rewrites[prevRop->instructionIndex] = nullptr; // kill first delete
rop->index = std::min(prevRop->index, rop->index);
rop->lastIndex = std::max(prevRop->lastIndex, rop->lastIndex);
@ -407,6 +411,7 @@ std::unordered_map<size_t, TokenStreamRewriter::RewriteOperation*> TokenStreamRe
// whole token buffer so no lazy eval issue with any templates
iop->text = catOpText(&iop->text, &prevIop->text);
// delete redundant prior insert
delete rewrites[prevIop->instructionIndex];
rewrites[prevIop->instructionIndex] = nullptr;
}
}
@ -416,6 +421,7 @@ std::unordered_map<size_t, TokenStreamRewriter::RewriteOperation*> TokenStreamRe
for (auto rop : prevReplaces) {
if (iop->index == rop->index) {
rop->text = catOpText(&iop->text, &rop->text);
delete rewrites[i];
rewrites[i] = nullptr; // delete current insert
continue;
}

View File

@ -75,6 +75,12 @@ void ATNState::addTransition(Transition *e) {
}
void ATNState::addTransition(size_t index, Transition *e) {
for (Transition *transition : transitions)
if (transition->target->stateNumber == e->target->stateNumber) {
delete e;
return;
}
if (transitions.empty()) {
epsilonOnlyTransitions = e->isEpsilon();
} else if (epsilonOnlyTransitions != e->isEpsilon()) {