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:
parent
8450599e75
commit
af0ac9e2bb
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
|
Loading…
Reference in New Issue