From a60fcfed0ff356306c54c9f4c30598e827e3af2d Mon Sep 17 00:00:00 2001 From: Mike Lischke Date: Sun, 1 Jan 2017 17:39:44 +0100 Subject: [PATCH] Removed the need of a shadow s0 copy in the DFA class. --- .../runtime/src/atn/ParserATNSimulator.cpp | 2 ++ .../Cpp/runtime/src/atn/PredictionContext.cpp | 4 +++- runtime/Cpp/runtime/src/dfa/DFA.cpp | 21 +++++++++---------- runtime/Cpp/runtime/src/dfa/DFA.h | 5 ++--- .../v4/tool/templates/codegen/Cpp/Cpp.stg | 2 +- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp b/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp index 5d4aa146d..b15346ffe 100755 --- a/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp +++ b/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp @@ -124,6 +124,8 @@ size_t ParserATNSimulator::adaptivePredict(TokenStream *input, size_t decision, } else { dfa::DFAState *newState = new dfa::DFAState(std::move(s0_closure)); /* mem-check: managed by the DFA or deleted below */ s0 = addDFAState(dfa, newState); + + delete dfa.s0; // Delete existing s0 DFA state, if there's any. dfa.s0 = s0; if (s0 != newState) { delete newState; // If there was already a state with this config set we don't need the new one. diff --git a/runtime/Cpp/runtime/src/atn/PredictionContext.cpp b/runtime/Cpp/runtime/src/atn/PredictionContext.cpp index 9bee78451..86639d289 100755 --- a/runtime/Cpp/runtime/src/atn/PredictionContext.cpp +++ b/runtime/Cpp/runtime/src/atn/PredictionContext.cpp @@ -350,8 +350,10 @@ Ref PredictionContext::mergeArrays(const Ref(mergedParents, mergedReturnStates); + } if (mergeCache != nullptr) { mergeCache->put(a, b, M); diff --git a/runtime/Cpp/runtime/src/dfa/DFA.cpp b/runtime/Cpp/runtime/src/dfa/DFA.cpp index 309fdb27a..a637bf72c 100755 --- a/runtime/Cpp/runtime/src/dfa/DFA.cpp +++ b/runtime/Cpp/runtime/src/dfa/DFA.cpp @@ -26,35 +26,34 @@ DFA::DFA(atn::DecisionState *atnStartState, size_t decision) if (static_cast(atnStartState)->isPrecedenceDecision) { _precedenceDfa = true; s0 = new DFAState(std::unique_ptr(new atn::ATNConfigSet())); - _s0Shadow = s0; s0->isAcceptState = false; s0->requiresFullContext = false; } } } -DFA::DFA(DFA &&other) : atnStartState(std::move(other.atnStartState)), decision(std::move(other.decision)) { +DFA::DFA(DFA &&other) : atnStartState(other.atnStartState), decision(other.decision) { // Source states are implicitly cleared by the move. states = std::move(other.states); - // Manually move s0 pointers. + other.atnStartState = nullptr; + other.decision = 0; s0 = other.s0; other.s0 = nullptr; - _s0Shadow = other._s0Shadow; - other._s0Shadow = nullptr; - _precedenceDfa = other._precedenceDfa; + other._precedenceDfa = false; } DFA::~DFA() { - // ml: s0 can be set either in our constructor or by external code, so we need a way to track our own creation. - // We could use a shared pointer again (and force that on all external assignments etc.) or just shadow it. - // I hesitate moving s0 to the normal states list as this might conflict with consumers of that list. - delete _s0Shadow; - + bool s0InList = (s0 == nullptr); for (auto state : states) { + if (state == s0) + s0InList = true; delete state; } + + if (!s0InList) + delete s0; } bool DFA::isPrecedenceDfa() const { diff --git a/runtime/Cpp/runtime/src/dfa/DFA.h b/runtime/Cpp/runtime/src/dfa/DFA.h index b5d061ac4..7d2f653c1 100755 --- a/runtime/Cpp/runtime/src/dfa/DFA.h +++ b/runtime/Cpp/runtime/src/dfa/DFA.h @@ -20,10 +20,10 @@ namespace dfa { /// Set only allows you to see if it's there. /// From which ATN state did we create this DFA? - atn::DecisionState *const atnStartState; + atn::DecisionState *atnStartState; std::unordered_set states; // States are owned by this class. DFAState *s0; - const size_t decision; + size_t decision; DFA(atn::DecisionState *atnStartState); DFA(atn::DecisionState *atnStartState, size_t decision); @@ -85,7 +85,6 @@ namespace dfa { * {@code false}. This is the backing field for {@link #isPrecedenceDfa}. */ bool _precedenceDfa; - DFAState *_s0Shadow = nullptr; // ml: assigned when we created s0 ourselves. }; } // namespace atn diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Cpp/Cpp.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Cpp/Cpp.stg index 78f961083..4e9352475 100644 --- a/tool/resources/org/antlr/v4/tool/templates/codegen/Cpp/Cpp.stg +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Cpp/Cpp.stg @@ -1014,7 +1014,7 @@ ContextRuleListIndexedGetterDecl(r) ::= << >> -LexerRuleContext() ::= "antlr4::RuleContext" +LexerRuleContext() ::= "RuleContext" // The rule context name is the rule followed by a suffix; e.g. r becomes rContext. RuleContextNameSuffix() ::= "Context"