diff --git a/runtime/Cpp/runtime/src/Parser.cpp b/runtime/Cpp/runtime/src/Parser.cpp index e9e887365c3..f0e6fab78a4 100755 --- a/runtime/Cpp/runtime/src/Parser.cpp +++ b/runtime/Cpp/runtime/src/Parser.cpp @@ -28,10 +28,25 @@ using namespace antlr4; using namespace antlr4::atn; - using namespace antlrcpp; -std::map, atn::ATN> Parser::bypassAltsAtnCache; +namespace { + +struct BypassAltsAtnCache final { + std::shared_mutex mutex; + /// This field maps from the serialized ATN string to the deserialized with + /// bypass alternatives. + /// + /// + std::map, std::unique_ptr> map; +}; + +BypassAltsAtnCache* getBypassAltsAtnCache() { + static BypassAltsAtnCache* const instance = new BypassAltsAtnCache(); + return instance; +} + +} Parser::TraceListener::TraceListener(Parser *outerInstance_) : outerInstance(outerInstance_) { } @@ -214,25 +229,29 @@ TokenFactory* Parser::getTokenFactory() { const atn::ATN& Parser::getATNWithBypassAlts() { - std::vector serializedAtn = getSerializedATN(); + const std::vector &serializedAtn = getSerializedATN(); if (serializedAtn.empty()) { throw UnsupportedOperationException("The current parser does not support an ATN with bypass alternatives."); } - std::lock_guard lck(_mutex); - - // XXX: using the entire serialized ATN as key into the map is a big resource waste. - // How large can that thing become? - if (bypassAltsAtnCache.find(serializedAtn) == bypassAltsAtnCache.end()) + auto *cache = getBypassAltsAtnCache(); { - atn::ATNDeserializationOptions deserializationOptions; - deserializationOptions.setGenerateRuleBypassTransitions(true); - - atn::ATNDeserializer deserializer(deserializationOptions); - bypassAltsAtnCache[serializedAtn] = deserializer.deserialize(serializedAtn); + std::shared_lock lock(cache->mutex); + auto existing = cache->map.find(serializedAtn); + if (existing != cache->map.end()) { + return *existing->second; + } } - return bypassAltsAtnCache[serializedAtn]; + atn::ATNDeserializationOptions deserializationOptions; + deserializationOptions.setGenerateRuleBypassTransitions(true); + atn::ATNDeserializer deserializer(deserializationOptions); + auto atn = deserializer.deserialize(serializedAtn); + + { + std::unique_lock lock(cache->mutex); + return *cache->map.insert(std::make_pair(serializedAtn, std::move(atn))).first->second; + } } tree::pattern::ParseTreePattern Parser::compileParseTreePattern(const std::string &pattern, int patternRuleIndex) { diff --git a/runtime/Cpp/runtime/src/Parser.h b/runtime/Cpp/runtime/src/Parser.h index 2cdd66689b5..4d735da68dd 100755 --- a/runtime/Cpp/runtime/src/Parser.h +++ b/runtime/Cpp/runtime/src/Parser.h @@ -448,12 +448,6 @@ namespace antlr4 { tree::ParseTreeTracker _tracker; private: - /// This field maps from the serialized ATN string to the deserialized with - /// bypass alternatives. - /// - /// - static std::map, atn::ATN> bypassAltsAtnCache; - /// When setTrace(true) is called, a reference to the /// TraceListener is stored here so it can be easily removed in a /// later call to setTrace(false). The listener itself is diff --git a/runtime/Cpp/runtime/src/Recognizer.h b/runtime/Cpp/runtime/src/Recognizer.h index 482795fe799..932e726675b 100755 --- a/runtime/Cpp/runtime/src/Recognizer.h +++ b/runtime/Cpp/runtime/src/Recognizer.h @@ -53,7 +53,7 @@ namespace antlr4 { /// For interpreters, we don't know their serialized ATN despite having /// created the interpreter from it. /// - virtual const std::vector getSerializedATN() const { + virtual const std::vector& getSerializedATN() const { throw "there is no serialized ATN"; } diff --git a/runtime/Cpp/runtime/src/atn/ATN.cpp b/runtime/Cpp/runtime/src/atn/ATN.cpp index 8336703cdce..20a320d8e24 100755 --- a/runtime/Cpp/runtime/src/atn/ATN.cpp +++ b/runtime/Cpp/runtime/src/atn/ATN.cpp @@ -20,24 +20,9 @@ using namespace antlr4; using namespace antlr4::atn; using namespace antlrcpp; -ATN::ATN() : ATN(ATNType::LEXER, 0) { -} +ATN::ATN() : ATN(ATNType::LEXER, 0) {} -ATN::ATN(ATN &&other) { - // All source vectors are implicitly cleared by the moves. - states = std::move(other.states); - decisionToState = std::move(other.decisionToState); - ruleToStartState = std::move(other.ruleToStartState); - ruleToStopState = std::move(other.ruleToStopState); - grammarType = std::move(other.grammarType); - maxTokenType = std::move(other.maxTokenType); - ruleToTokenType = std::move(other.ruleToTokenType); - lexerActions = std::move(other.lexerActions); - modeToStartState = std::move(other.modeToStartState); -} - -ATN::ATN(ATNType grammarType_, size_t maxTokenType_) : grammarType(grammarType_), maxTokenType(maxTokenType_) { -} +ATN::ATN(ATNType grammarType_, size_t maxTokenType_) : grammarType(grammarType_), maxTokenType(maxTokenType_) {} ATN::~ATN() { for (ATNState *state : states) { @@ -45,42 +30,6 @@ ATN::~ATN() { } } -/** - * Required to be defined (even though not used) as we have an explicit move assignment operator. - */ -ATN& ATN::operator = (ATN &other) noexcept { - states = other.states; - decisionToState = other.decisionToState; - ruleToStartState = other.ruleToStartState; - ruleToStopState = other.ruleToStopState; - grammarType = other.grammarType; - maxTokenType = other.maxTokenType; - ruleToTokenType = other.ruleToTokenType; - lexerActions = other.lexerActions; - modeToStartState = other.modeToStartState; - - return *this; -} - -/** - * Explicit move assignment operator to make this the preferred assignment. With implicit copy/move assignment - * operators it seems the copy operator is preferred causing trouble when releasing the allocated ATNState instances. - */ -ATN& ATN::operator = (ATN &&other) noexcept { - // All source vectors are implicitly cleared by the moves. - states = std::move(other.states); - decisionToState = std::move(other.decisionToState); - ruleToStartState = std::move(other.ruleToStartState); - ruleToStopState = std::move(other.ruleToStopState); - grammarType = std::move(other.grammarType); - maxTokenType = std::move(other.maxTokenType); - ruleToTokenType = std::move(other.ruleToTokenType); - lexerActions = std::move(other.lexerActions); - modeToStartState = std::move(other.modeToStartState); - - return *this; -} - misc::IntervalSet ATN::nextTokens(ATNState *s, RuleContext *ctx) const { LL1Analyzer analyzer(*this); return analyzer.LOOK(s, ctx); @@ -89,7 +38,7 @@ misc::IntervalSet ATN::nextTokens(ATNState *s, RuleContext *ctx) const { misc::IntervalSet const& ATN::nextTokens(ATNState *s) const { if (!s->_nextTokenUpdated) { - std::unique_lock lock { _mutex }; + std::unique_lock lock(_mutex); if (!s->_nextTokenUpdated) { s->_nextTokenWithinRule = nextTokens(s, nullptr); s->_nextTokenUpdated = true; diff --git a/runtime/Cpp/runtime/src/atn/ATN.h b/runtime/Cpp/runtime/src/atn/ATN.h index 9e84e11614f..aa811e0ce0f 100755 --- a/runtime/Cpp/runtime/src/atn/ATN.h +++ b/runtime/Cpp/runtime/src/atn/ATN.h @@ -16,15 +16,27 @@ namespace antlr4 { namespace atn { + class LexerATNSimulator; + class ParserATNSimulator; + class ANTLR4CPP_PUBLIC ATN { public: static constexpr size_t INVALID_ALT_NUMBER = 0; /// Used for runtime deserialization of ATNs from strings. ATN(); - ATN(ATN &&other); + ATN(ATNType grammarType, size_t maxTokenType); - virtual ~ATN(); + + ATN(const ATN&) = delete; + + ATN(ATN&&) = delete; + + ~ATN(); + + ATN& operator=(const ATN&) = delete; + + ATN& operator=(ATN&&) = delete; std::vector states; @@ -60,33 +72,30 @@ namespace atn { std::vector modeToStartState; - ATN& operator = (ATN &other) noexcept; - ATN& operator = (ATN &&other) noexcept; - /// /// Compute the set of valid tokens that can occur starting in state {@code s}. /// If {@code ctx} is null, the set of tokens will not include what can follow /// the rule surrounding {@code s}. In other words, the set will be /// restricted to tokens reachable staying within {@code s}'s rule. /// - virtual misc::IntervalSet nextTokens(ATNState *s, RuleContext *ctx) const; + misc::IntervalSet nextTokens(ATNState *s, RuleContext *ctx) const; /// /// Compute the set of valid tokens that can occur starting in {@code s} and /// staying in same rule. is in set if we reach end of /// rule. /// - virtual misc::IntervalSet const& nextTokens(ATNState *s) const; + misc::IntervalSet const& nextTokens(ATNState *s) const; - virtual void addState(ATNState *state); + void addState(ATNState *state); - virtual void removeState(ATNState *state); + void removeState(ATNState *state); - virtual int defineDecisionState(DecisionState *s); + int defineDecisionState(DecisionState *s); - virtual DecisionState *getDecisionState(size_t decision) const; + DecisionState *getDecisionState(size_t decision) const; - virtual size_t getNumberOfDecisions() const; + size_t getNumberOfDecisions() const; /// /// Computes the set of input symbols which could follow ATN state number @@ -106,12 +115,17 @@ namespace atn { /// specified state in the specified context. /// if the ATN does not contain a state with /// number {@code stateNumber} - virtual misc::IntervalSet getExpectedTokens(size_t stateNumber, RuleContext *context) const; + misc::IntervalSet getExpectedTokens(size_t stateNumber, RuleContext *context) const; std::string toString() const; private: + friend class LexerATNSimulator; + friend class ParserATNSimulator; + mutable std::mutex _mutex; + mutable std::shared_mutex _stateMutex; + mutable std::shared_mutex _edgeMutex; }; } // namespace atn diff --git a/runtime/Cpp/runtime/src/atn/ATNDeserializer.cpp b/runtime/Cpp/runtime/src/atn/ATNDeserializer.cpp index a351a53d686..f7301f6245d 100755 --- a/runtime/Cpp/runtime/src/atn/ATNDeserializer.cpp +++ b/runtime/Cpp/runtime/src/atn/ATNDeserializer.cpp @@ -179,7 +179,7 @@ ATNDeserializer::ATNDeserializer() : ATNDeserializer(ATNDeserializationOptions:: ATNDeserializer::ATNDeserializer(ATNDeserializationOptions deserializationOptions) : _deserializationOptions(std::move(deserializationOptions)) {} -ATN ATNDeserializer::deserialize(const std::vector& data) const { +std::unique_ptr ATNDeserializer::deserialize(const std::vector& data) const { int p = 0; int version = data[p++]; if (version != SERIALIZED_VERSION) { @@ -190,7 +190,7 @@ ATN ATNDeserializer::deserialize(const std::vector& data) const { ATNType grammarType = (ATNType)data[p++]; size_t maxTokenType = data[p++]; - ATN atn(grammarType, maxTokenType); + auto atn = std::make_unique(grammarType, maxTokenType); // // STATES @@ -199,14 +199,14 @@ ATN ATNDeserializer::deserialize(const std::vector& data) const { std::vector> loopBackStateNumbers; std::vector> endStateNumbers; size_t nstates = data[p++]; - atn.states.reserve(nstates); + atn->states.reserve(nstates); loopBackStateNumbers.reserve(nstates); // Reserve worst case size, its short lived. endStateNumbers.reserve(nstates); // Reserve worst case size, its short lived. for (size_t i = 0; i < nstates; i++) { size_t stype = data[p++]; // ignore bad type of states if (stype == ATNState::ATN_INVALID_TYPE) { - atn.addState(nullptr); + atn->addState(nullptr); continue; } @@ -223,16 +223,16 @@ ATN ATNDeserializer::deserialize(const std::vector& data) const { int endStateNumber = data[p++]; endStateNumbers.push_back({ downCast(s), endStateNumber }); } - atn.addState(s); + atn->addState(s); } // delay the assignment of loop back and end states until we know all the state instances have been initialized for (auto &pair : loopBackStateNumbers) { - pair.first->loopBackState = atn.states[pair.second]; + pair.first->loopBackState = atn->states[pair.second]; } for (auto &pair : endStateNumbers) { - pair.first->endState = downCast(atn.states[pair.second]); + pair.first->endState = downCast(atn->states[pair.second]); } } @@ -241,54 +241,54 @@ ATN ATNDeserializer::deserialize(const std::vector& data) const { size_t stateNumber = data[p++]; // The serialized ATN must be specifying the right states, so that the // cast below is correct. - downCast(atn.states[stateNumber])->nonGreedy = true; + downCast(atn->states[stateNumber])->nonGreedy = true; } size_t numPrecedenceStates = data[p++]; for (size_t i = 0; i < numPrecedenceStates; i++) { size_t stateNumber = data[p++]; - downCast(atn.states[stateNumber])->isLeftRecursiveRule = true; + downCast(atn->states[stateNumber])->isLeftRecursiveRule = true; } // // RULES // size_t nrules = data[p++]; - atn.ruleToStartState.reserve(nrules); + atn->ruleToStartState.reserve(nrules); for (size_t i = 0; i < nrules; i++) { size_t s = data[p++]; // Also here, the serialized atn must ensure to point to the correct class type. - RuleStartState *startState = downCast(atn.states[s]); - atn.ruleToStartState.push_back(startState); - if (atn.grammarType == ATNType::LEXER) { + RuleStartState *startState = downCast(atn->states[s]); + atn->ruleToStartState.push_back(startState); + if (atn->grammarType == ATNType::LEXER) { size_t tokenType = data[p++]; if (tokenType == 0xFFFF) { tokenType = Token::EOF; } - atn.ruleToTokenType.push_back(tokenType); + atn->ruleToTokenType.push_back(tokenType); } } - atn.ruleToStopState.resize(nrules); - for (ATNState *state : atn.states) { + atn->ruleToStopState.resize(nrules); + for (ATNState *state : atn->states) { if (!is(state)) { continue; } RuleStopState *stopState = downCast(state); - atn.ruleToStopState[state->ruleIndex] = stopState; - atn.ruleToStartState[state->ruleIndex]->stopState = stopState; + atn->ruleToStopState[state->ruleIndex] = stopState; + atn->ruleToStartState[state->ruleIndex]->stopState = stopState; } // // MODES // size_t nmodes = data[p++]; - atn.modeToStartState.reserve(nmodes); + atn->modeToStartState.reserve(nmodes); for (size_t i = 0; i < nmodes; i++) { size_t s = data[p++]; - atn.modeToStartState.push_back(downCast(atn.states[s])); + atn->modeToStartState.push_back(downCast(atn->states[s])); } // @@ -316,14 +316,14 @@ ATN ATNDeserializer::deserialize(const std::vector& data) const { size_t arg1 = data[p + 3]; size_t arg2 = data[p + 4]; size_t arg3 = data[p + 5]; - ConstTransitionPtr trans = edgeFactory(atn, ttype, src, trg, arg1, arg2, arg3, sets); - ATNState *srcState = atn.states[src]; + ConstTransitionPtr trans = edgeFactory(*atn, ttype, src, trg, arg1, arg2, arg3, sets); + ATNState *srcState = atn->states[src]; srcState->addTransition(std::move(trans)); p += 6; } } // edges for rule stop states can be derived, so they aren't serialized - for (ATNState *state : atn.states) { + for (ATNState *state : atn->states) { for (size_t i = 0; i < state->transitions.size(); i++) { const Transition *t = state->transitions[i].get(); if (!is(t)) { @@ -332,18 +332,18 @@ ATN ATNDeserializer::deserialize(const std::vector& data) const { const RuleTransition *ruleTransition = downCast(t); size_t outermostPrecedenceReturn = INVALID_INDEX; - if (atn.ruleToStartState[ruleTransition->target->ruleIndex]->isLeftRecursiveRule) { + if (atn->ruleToStartState[ruleTransition->target->ruleIndex]->isLeftRecursiveRule) { if (ruleTransition->precedence == 0) { outermostPrecedenceReturn = ruleTransition->target->ruleIndex; } } ConstTransitionPtr returnTransition = std::make_unique(ruleTransition->followState, outermostPrecedenceReturn); - atn.ruleToStopState[ruleTransition->target->ruleIndex]->addTransition(std::move(returnTransition)); + atn->ruleToStopState[ruleTransition->target->ruleIndex]->addTransition(std::move(returnTransition)); } } - for (ATNState *state : atn.states) { + for (ATNState *state : atn->states) { if (is(state)) { BlockStartState *startState = downCast(state); @@ -383,23 +383,23 @@ ATN ATNDeserializer::deserialize(const std::vector& data) const { // DECISIONS // size_t ndecisions = data[p++]; - atn.decisionToState.reserve(ndecisions); + atn->decisionToState.reserve(ndecisions); for (size_t i = 0; i < ndecisions; i++) { size_t s = data[p++]; - DecisionState *decState = downCast(atn.states[s]); + DecisionState *decState = downCast(atn->states[s]); if (decState == nullptr) throw IllegalStateException(); - atn.decisionToState.push_back(decState); + atn->decisionToState.push_back(decState); decState->decision = static_cast(i); } // // LEXER ACTIONS // - if (atn.grammarType == ATNType::LEXER) { - atn.lexerActions.resize(data[p++]); - for (size_t i = 0; i < atn.lexerActions.size(); i++) { + if (atn->grammarType == ATNType::LEXER) { + atn->lexerActions.resize(data[p++]); + for (size_t i = 0; i < atn->lexerActions.size(); i++) { LexerActionType actionType = static_cast(data[p++]); int data1 = data[p++]; if (data1 == 0xFFFF) { @@ -411,42 +411,42 @@ ATN ATNDeserializer::deserialize(const std::vector& data) const { data2 = -1; } - atn.lexerActions[i] = lexerActionFactory(actionType, data1, data2); + atn->lexerActions[i] = lexerActionFactory(actionType, data1, data2); } } - markPrecedenceDecisions(atn); + markPrecedenceDecisions(*atn); if (_deserializationOptions.isVerifyATN()) { - verifyATN(atn); + verifyATN(*atn); } - if (_deserializationOptions.isGenerateRuleBypassTransitions() && atn.grammarType == ATNType::PARSER) { - atn.ruleToTokenType.resize(atn.ruleToStartState.size()); - for (size_t i = 0; i < atn.ruleToStartState.size(); i++) { - atn.ruleToTokenType[i] = static_cast(atn.maxTokenType + i + 1); + if (_deserializationOptions.isGenerateRuleBypassTransitions() && atn->grammarType == ATNType::PARSER) { + atn->ruleToTokenType.resize(atn->ruleToStartState.size()); + for (size_t i = 0; i < atn->ruleToStartState.size(); i++) { + atn->ruleToTokenType[i] = static_cast(atn->maxTokenType + i + 1); } - for (std::vector::size_type i = 0; i < atn.ruleToStartState.size(); i++) { + for (std::vector::size_type i = 0; i < atn->ruleToStartState.size(); i++) { BasicBlockStartState *bypassStart = new BasicBlockStartState(); /* mem check: freed in ATN d-tor */ bypassStart->ruleIndex = static_cast(i); - atn.addState(bypassStart); + atn->addState(bypassStart); BlockEndState *bypassStop = new BlockEndState(); /* mem check: freed in ATN d-tor */ bypassStop->ruleIndex = static_cast(i); - atn.addState(bypassStop); + atn->addState(bypassStop); bypassStart->endState = bypassStop; - atn.defineDecisionState(bypassStart); + atn->defineDecisionState(bypassStart); bypassStop->startState = bypassStart; ATNState *endState; const Transition *excludeTransition = nullptr; - if (atn.ruleToStartState[i]->isLeftRecursiveRule) { + if (atn->ruleToStartState[i]->isLeftRecursiveRule) { // wrap from the beginning of the rule to the StarLoopEntryState endState = nullptr; - for (ATNState *state : atn.states) { + for (ATNState *state : atn->states) { if (state->ruleIndex != i) { continue; } @@ -473,11 +473,11 @@ ATN ATNDeserializer::deserialize(const std::vector& data) const { excludeTransition = (static_cast(endState))->loopBackState->transitions[0].get(); } else { - endState = atn.ruleToStopState[i]; + endState = atn->ruleToStopState[i]; } // all non-excluded transitions that currently target end state need to target blockEnd instead - for (ATNState *state : atn.states) { + for (ATNState *state : atn->states) { for (auto &transition : state->transitions) { if (transition.get() == excludeTransition) { continue; @@ -490,24 +490,24 @@ ATN ATNDeserializer::deserialize(const std::vector& data) const { } // all transitions leaving the rule start state need to leave blockStart instead - while (atn.ruleToStartState[i]->transitions.size() > 0) { - ConstTransitionPtr transition = atn.ruleToStartState[i]->removeTransition(atn.ruleToStartState[i]->transitions.size() - 1); + while (atn->ruleToStartState[i]->transitions.size() > 0) { + ConstTransitionPtr transition = atn->ruleToStartState[i]->removeTransition(atn->ruleToStartState[i]->transitions.size() - 1); bypassStart->addTransition(std::move(transition)); } // link the new states - atn.ruleToStartState[i]->addTransition(std::make_unique(bypassStart)); + atn->ruleToStartState[i]->addTransition(std::make_unique(bypassStart)); bypassStop->addTransition(std::make_unique(endState)); ATNState *matchState = new BasicState(); /* mem check: freed in ATN d-tor */ - atn.addState(matchState); - matchState->addTransition(std::make_unique(bypassStop, atn.ruleToTokenType[i])); + atn->addState(matchState); + matchState->addTransition(std::make_unique(bypassStop, atn->ruleToTokenType[i])); bypassStart->addTransition(std::make_unique(matchState)); } if (_deserializationOptions.isVerifyATN()) { // reverify after modification - verifyATN(atn); + verifyATN(*atn); } } diff --git a/runtime/Cpp/runtime/src/atn/ATNDeserializer.h b/runtime/Cpp/runtime/src/atn/ATNDeserializer.h index 17ae0275c89..19a38077d1b 100755 --- a/runtime/Cpp/runtime/src/atn/ATNDeserializer.h +++ b/runtime/Cpp/runtime/src/atn/ATNDeserializer.h @@ -20,7 +20,7 @@ namespace atn { explicit ATNDeserializer(ATNDeserializationOptions deserializationOptions); - ATN deserialize(const std::vector &input) const; + std::unique_ptr deserialize(const std::vector &input) const; void verifyATN(const ATN &atn) const; static ConstTransitionPtr edgeFactory(const ATN &atn, size_t type, size_t src, size_t trg, size_t arg1, size_t arg2, diff --git a/runtime/Cpp/runtime/src/atn/ATNSimulator.cpp b/runtime/Cpp/runtime/src/atn/ATNSimulator.cpp index 00ce9ec1907..72912a3da40 100755 --- a/runtime/Cpp/runtime/src/atn/ATNSimulator.cpp +++ b/runtime/Cpp/runtime/src/atn/ATNSimulator.cpp @@ -16,8 +16,6 @@ using namespace antlr4::dfa; using namespace antlr4::atn; const Ref ATNSimulator::ERROR = std::make_shared(std::numeric_limits::max()); -std::shared_mutex ATNSimulator::_stateLock; -std::shared_mutex ATNSimulator::_edgeLock; ATNSimulator::ATNSimulator(const ATN &atn, PredictionContextCache &sharedContextCache) : atn(atn), _sharedContextCache(sharedContextCache) {} diff --git a/runtime/Cpp/runtime/src/atn/ATNSimulator.h b/runtime/Cpp/runtime/src/atn/ATNSimulator.h index b0de2cbfeb4..2dfb4bd953f 100755 --- a/runtime/Cpp/runtime/src/atn/ATNSimulator.h +++ b/runtime/Cpp/runtime/src/atn/ATNSimulator.h @@ -41,9 +41,6 @@ namespace atn { virtual Ref getCachedContext(Ref const& context); protected: - static std::shared_mutex _stateLock; // Lock for DFA states. - static std::shared_mutex _edgeLock; // Lock for the sparse edge map in DFA states. - /// /// The context cache maps all PredictionContext objects that are equals() /// to a single cached copy. This cache is shared across all contexts diff --git a/runtime/Cpp/runtime/src/atn/LexerATNSimulator.cpp b/runtime/Cpp/runtime/src/atn/LexerATNSimulator.cpp index c33afe0183f..f300e057a0c 100755 --- a/runtime/Cpp/runtime/src/atn/LexerATNSimulator.cpp +++ b/runtime/Cpp/runtime/src/atn/LexerATNSimulator.cpp @@ -80,9 +80,11 @@ size_t LexerATNSimulator::match(CharStream *input, size_t mode) { _startIndex = input->index(); _prevAccept.reset(); const dfa::DFA &dfa = _decisionToDFA[mode]; - _stateLock.lock_shared(); - dfa::DFAState* s0 = dfa.s0; - _stateLock.unlock_shared(); + dfa::DFAState* s0; + { + std::shared_lock stateLock(atn._stateMutex); + s0 = dfa.s0; + } if (s0 == nullptr) { return matchATN(input); } else { @@ -182,7 +184,7 @@ size_t LexerATNSimulator::execATN(CharStream *input, dfa::DFAState *ds0) { dfa::DFAState *LexerATNSimulator::getExistingTargetState(dfa::DFAState *s, size_t t) { dfa::DFAState* retval = nullptr; - _edgeLock.lock_shared(); + std::shared_lock edgeLock(atn._edgeMutex); if (t <= MAX_DFA_EDGE) { auto iterator = s->edges.find(t - MIN_DFA_EDGE); #if DEBUG_ATN == 1 @@ -194,7 +196,6 @@ dfa::DFAState *LexerATNSimulator::getExistingTargetState(dfa::DFAState *s, size_ if (iterator != s->edges.end()) retval = iterator->second; } - _edgeLock.unlock_shared(); return retval; } @@ -530,9 +531,8 @@ void LexerATNSimulator::addDFAEdge(dfa::DFAState *p, size_t t, dfa::DFAState *q) return; } - _edgeLock.lock(); + std::unique_lock edgeLock(atn._edgeMutex); p->edges[t - MIN_DFA_EDGE] = q; // connect - _edgeLock.unlock(); } dfa::DFAState *LexerATNSimulator::addDFAState(ATNConfigSet *configs) { @@ -563,7 +563,7 @@ dfa::DFAState *LexerATNSimulator::addDFAState(ATNConfigSet *configs, bool suppre dfa::DFA &dfa = _decisionToDFA[_mode]; { - std::unique_lock stateLock(_stateLock); + std::unique_lock stateLock(atn._stateMutex); auto [existing, inserted] = dfa.states.insert(proposed); if (!inserted) { delete proposed; diff --git a/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp b/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp index 3a3a4d15b04..3186742705d 100755 --- a/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp +++ b/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp @@ -95,11 +95,11 @@ size_t ParserATNSimulator::adaptivePredict(TokenStream *input, size_t decision, dfa::DFAState *s0; { - std::shared_lock stateLock(_stateLock); + std::shared_lock stateLock(atn._stateMutex); if (dfa.isPrecedenceDfa()) { // the start state for a precedence DFA depends on the current // parser precedence, and is provided by a DFA method. - std::shared_lock edgeLock(_edgeLock); + std::shared_lock edgeLock(atn._edgeMutex); s0 = dfa.getPrecedenceStartState(parser->getPrecedence()); } else { // the start state for a "regular" DFA is just s0 @@ -112,7 +112,7 @@ size_t ParserATNSimulator::adaptivePredict(TokenStream *input, size_t decision, std::unique_ptr s0_closure = computeStartState(dfa.atnStartState, &ParserRuleContext::EMPTY, fullCtx); - _stateLock.lock(); + std::unique_lock stateLock(atn._stateMutex); dfa::DFAState* ds0 = dfa.s0; if (dfa.isPrecedenceDfa()) { /* If this is a precedence DFA, we use applyPrecedenceFilter @@ -124,7 +124,8 @@ size_t ParserATNSimulator::adaptivePredict(TokenStream *input, size_t decision, ds0->configs = std::move(s0_closure); // not used for prediction but useful to know start configs anyway dfa::DFAState *newState = new dfa::DFAState(applyPrecedenceFilter(ds0->configs.get())); /* mem-check: managed by the DFA or deleted below */ s0 = addDFAState(dfa, newState); - dfa.setPrecedenceStartState(parser->getPrecedence(), s0, _edgeLock); + std::unique_lock edgeLock(atn._edgeMutex); + dfa.setPrecedenceStartState(parser->getPrecedence(), s0); if (s0 != newState) { delete newState; // If there was already a state with this config set we don't need the new one. } @@ -141,7 +142,6 @@ size_t ParserATNSimulator::adaptivePredict(TokenStream *input, size_t decision, delete newState; // If there was already a state with this config set we don't need the new one. } } - _stateLock.unlock(); } // We can start with an existing DFA. @@ -266,10 +266,9 @@ size_t ParserATNSimulator::execATN(dfa::DFA &dfa, dfa::DFAState *s0, TokenStream dfa::DFAState *ParserATNSimulator::getExistingTargetState(dfa::DFAState *previousD, size_t t) { dfa::DFAState* retval; - _edgeLock.lock_shared(); + std::shared_lock edgeLock(atn._edgeMutex); auto iterator = previousD->edges.find(t); retval = (iterator == previousD->edges.end()) ? nullptr : iterator->second; - _edgeLock.unlock_shared(); return retval; } @@ -1255,17 +1254,17 @@ dfa::DFAState *ParserATNSimulator::addDFAEdge(dfa::DFA &dfa, dfa::DFAState *from return nullptr; } - _stateLock.lock(); - to = addDFAState(dfa, to); // used existing if possible not incoming - _stateLock.unlock(); + { + std::unique_lock stateLock(atn._stateMutex); + to = addDFAState(dfa, to); // used existing if possible not incoming + } if (from == nullptr || t > (int)atn.maxTokenType) { return to; } { - _edgeLock.lock(); + std::unique_lock edgeLock(atn._edgeMutex); from->edges[t] = to; // connect - _edgeLock.unlock(); } #if DEBUG_DFA == 1 diff --git a/runtime/Cpp/runtime/src/dfa/DFA.cpp b/runtime/Cpp/runtime/src/dfa/DFA.cpp index 10b4ddddb18..5c11b14bdf5 100755 --- a/runtime/Cpp/runtime/src/dfa/DFA.cpp +++ b/runtime/Cpp/runtime/src/dfa/DFA.cpp @@ -70,7 +70,7 @@ DFAState* DFA::getPrecedenceStartState(int precedence) const { return iterator->second; } -void DFA::setPrecedenceStartState(int precedence, DFAState *startState, std::shared_mutex &lock) { +void DFA::setPrecedenceStartState(int precedence, DFAState *startState) { if (!isPrecedenceDfa()) { throw IllegalStateException("Only precedence DFAs may contain a precedence start state."); } @@ -79,11 +79,7 @@ void DFA::setPrecedenceStartState(int precedence, DFAState *startState, std::sha return; } - { - lock.lock(); - s0->edges[precedence] = startState; - lock.unlock(); - } + s0->edges[precedence] = startState; } std::vector DFA::getStates() const { diff --git a/runtime/Cpp/runtime/src/dfa/DFA.h b/runtime/Cpp/runtime/src/dfa/DFA.h index 870652f10e9..9ebb87503dc 100755 --- a/runtime/Cpp/runtime/src/dfa/DFA.h +++ b/runtime/Cpp/runtime/src/dfa/DFA.h @@ -62,7 +62,7 @@ namespace dfa { * @throws IllegalStateException if this is not a precedence DFA. * @see #isPrecedenceDfa() */ - void setPrecedenceStartState(int precedence, DFAState *startState, std::shared_mutex &lock); + void setPrecedenceStartState(int precedence, DFAState *startState); /// Return a list of all states in this DFA, ordered by state number. std::vector getStates() const; diff --git a/runtime/Cpp/runtime/src/misc/InterpreterDataReader.h b/runtime/Cpp/runtime/src/misc/InterpreterDataReader.h index 37fc957e090..c0cf9880a18 100755 --- a/runtime/Cpp/runtime/src/misc/InterpreterDataReader.h +++ b/runtime/Cpp/runtime/src/misc/InterpreterDataReader.h @@ -13,7 +13,7 @@ namespace antlr4 { namespace misc { struct InterpreterData { - atn::ATN atn; + std::unique_ptr atn; dfa::Vocabulary vocabulary; std::vector ruleNames; std::vector channels; // Only valid for lexer grammars. diff --git a/runtime/Cpp/runtime/src/tree/xpath/XPathLexer.cpp b/runtime/Cpp/runtime/src/tree/xpath/XPathLexer.cpp index cf63327f0b6..6b0e93d9432 100644 --- a/runtime/Cpp/runtime/src/tree/xpath/XPathLexer.cpp +++ b/runtime/Cpp/runtime/src/tree/xpath/XPathLexer.cpp @@ -9,7 +9,7 @@ using namespace antlr4; XPathLexer::XPathLexer(CharStream *input) : Lexer(input) { - _interpreter = new atn::LexerATNSimulator(this, _atn, _decisionToDFA, _sharedContextCache); + _interpreter = new atn::LexerATNSimulator(this, *_atn, *_decisionToDFA, _sharedContextCache); } XPathLexer::~XPathLexer() { @@ -36,12 +36,12 @@ dfa::Vocabulary& XPathLexer::getVocabulary() const { return _vocabulary; } -const std::vector XPathLexer::getSerializedATN() const { +const std::vector& XPathLexer::getSerializedATN() const { return _serializedATN; } const atn::ATN& XPathLexer::getATN() const { - return _atn; + return *_atn; } @@ -56,7 +56,7 @@ void XPathLexer::action(RuleContext *context, size_t ruleIndex, size_t actionInd void XPathLexer::IDAction(antlr4::RuleContext *context, size_t actionIndex) { switch (actionIndex) { - case 0: + case 0: if (isupper(getText()[0])) setType(TOKEN_REF); else @@ -71,15 +71,15 @@ void XPathLexer::IDAction(antlr4::RuleContext *context, size_t actionIndex) { // Static vars and initialization. -std::vector XPathLexer::_decisionToDFA; +std::vector* XPathLexer::_decisionToDFA = nullptr; atn::PredictionContextCache XPathLexer::_sharedContextCache; // We own the ATN which in turn owns the ATN states. -atn::ATN XPathLexer::_atn; +atn::ATN* XPathLexer::_atn = nullptr; std::vector XPathLexer::_serializedATN; std::vector XPathLexer::_ruleNames = { - "ANYWHERE", "ROOT", "WILDCARD", "BANG", "ID", "NameChar", "NameStartChar", + "ANYWHERE", "ROOT", "WILDCARD", "BANG", "ID", "NameChar", "NameStartChar", "STRING" }; @@ -96,7 +96,7 @@ std::vector XPathLexer::_literalNames = { }; std::vector XPathLexer::_symbolicNames = { - "", "TOKEN_REF", "RULE_REF", "ANYWHERE", "ROOT", "WILDCARD", "BANG", "ID", + "", "TOKEN_REF", "RULE_REF", "ANYWHERE", "ROOT", "WILDCARD", "BANG", "ID", "STRING" }; @@ -104,44 +104,44 @@ dfa::Vocabulary XPathLexer::_vocabulary(_literalNames, _symbolicNames); XPathLexer::Initializer::Initializer() { static const uint16_t serializedATNSegment0[] = { - 0x4, 0x0, 0x8, 0x32, 0x6, 0xffff, 0x2, 0x0, 0x7, 0x0, 0x2, 0x1, 0x7, - 0x1, 0x2, 0x2, 0x7, 0x2, 0x2, 0x3, 0x7, 0x3, 0x2, 0x4, 0x7, 0x4, - 0x2, 0x5, 0x7, 0x5, 0x2, 0x6, 0x7, 0x6, 0x2, 0x7, 0x7, 0x7, 0x1, - 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, - 0x1, 0x3, 0x1, 0x3, 0x1, 0x4, 0x1, 0x4, 0x5, 0x4, 0x1d, 0x8, 0x4, - 0xa, 0x4, 0xc, 0x4, 0x20, 0x9, 0x4, 0x1, 0x4, 0x1, 0x4, 0x1, 0x5, - 0x1, 0x5, 0x3, 0x5, 0x26, 0x8, 0x5, 0x1, 0x6, 0x1, 0x6, 0x1, 0x7, - 0x1, 0x7, 0x5, 0x7, 0x2c, 0x8, 0x7, 0xa, 0x7, 0xc, 0x7, 0x2f, 0x9, - 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x2d, 0x0, 0x8, 0x1, 0x3, 0x3, 0x4, - 0x5, 0x5, 0x7, 0x6, 0x9, 0x7, 0xb, 0x0, 0xd, 0x0, 0xf, 0x8, 0x1, - 0x0, 0x2, 0x5, 0x0, 0x30, 0x39, 0x5f, 0x5f, 0xb7, 0xb7, 0x300, 0x36f, - 0x203f, 0x2040, 0xd, 0x0, 0x41, 0x5a, 0x61, 0x7a, 0xc0, 0xd6, 0xd8, - 0xf6, 0xf8, 0x2ff, 0x370, 0x37d, 0x37f, 0x1fff, 0x200c, 0x200d, 0x2070, - 0x218f, 0x2c00, 0x2fef, 0x3001, 0xd7ff, 0xf900, 0xfdcf, 0xfdf0, 0xffff, - 0x0, 0x32, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x3, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x5, 0x1, 0x0, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x1, 0x0, 0x0, 0x0, 0x0, 0xf, 0x1, 0x0, 0x0, 0x0, 0x1, - 0x11, 0x1, 0x0, 0x0, 0x0, 0x3, 0x14, 0x1, 0x0, 0x0, 0x0, 0x5, 0x16, - 0x1, 0x0, 0x0, 0x0, 0x7, 0x18, 0x1, 0x0, 0x0, 0x0, 0x9, 0x1a, 0x1, - 0x0, 0x0, 0x0, 0xb, 0x25, 0x1, 0x0, 0x0, 0x0, 0xd, 0x27, 0x1, 0x0, - 0x0, 0x0, 0xf, 0x29, 0x1, 0x0, 0x0, 0x0, 0x11, 0x12, 0x5, 0x2f, 0x0, - 0x0, 0x12, 0x13, 0x5, 0x2f, 0x0, 0x0, 0x13, 0x2, 0x1, 0x0, 0x0, 0x0, - 0x14, 0x15, 0x5, 0x2f, 0x0, 0x0, 0x15, 0x4, 0x1, 0x0, 0x0, 0x0, 0x16, - 0x17, 0x5, 0x2a, 0x0, 0x0, 0x17, 0x6, 0x1, 0x0, 0x0, 0x0, 0x18, 0x19, - 0x5, 0x21, 0x0, 0x0, 0x19, 0x8, 0x1, 0x0, 0x0, 0x0, 0x1a, 0x1e, 0x3, - 0xd, 0x6, 0x0, 0x1b, 0x1d, 0x3, 0xb, 0x5, 0x0, 0x1c, 0x1b, 0x1, 0x0, - 0x0, 0x0, 0x1d, 0x20, 0x1, 0x0, 0x0, 0x0, 0x1e, 0x1c, 0x1, 0x0, 0x0, - 0x0, 0x1e, 0x1f, 0x1, 0x0, 0x0, 0x0, 0x1f, 0x21, 0x1, 0x0, 0x0, 0x0, - 0x20, 0x1e, 0x1, 0x0, 0x0, 0x0, 0x21, 0x22, 0x6, 0x4, 0x0, 0x0, 0x22, - 0xa, 0x1, 0x0, 0x0, 0x0, 0x23, 0x26, 0x3, 0xd, 0x6, 0x0, 0x24, 0x26, - 0x7, 0x0, 0x0, 0x0, 0x25, 0x23, 0x1, 0x0, 0x0, 0x0, 0x25, 0x24, 0x1, - 0x0, 0x0, 0x0, 0x26, 0xc, 0x1, 0x0, 0x0, 0x0, 0x27, 0x28, 0x7, 0x1, - 0x0, 0x0, 0x28, 0xe, 0x1, 0x0, 0x0, 0x0, 0x29, 0x2d, 0x5, 0x27, 0x0, - 0x0, 0x2a, 0x2c, 0x9, 0x0, 0x0, 0x0, 0x2b, 0x2a, 0x1, 0x0, 0x0, 0x0, - 0x2c, 0x2f, 0x1, 0x0, 0x0, 0x0, 0x2d, 0x2e, 0x1, 0x0, 0x0, 0x0, 0x2d, - 0x2b, 0x1, 0x0, 0x0, 0x0, 0x2e, 0x30, 0x1, 0x0, 0x0, 0x0, 0x2f, 0x2d, - 0x1, 0x0, 0x0, 0x0, 0x30, 0x31, 0x5, 0x27, 0x0, 0x0, 0x31, 0x10, - 0x1, 0x0, 0x0, 0x0, 0x4, 0x0, 0x1e, 0x25, 0x2d, 0x1, 0x1, 0x4, 0x0, + 0x4, 0x0, 0x8, 0x32, 0x6, 0xffff, 0x2, 0x0, 0x7, 0x0, 0x2, 0x1, 0x7, + 0x1, 0x2, 0x2, 0x7, 0x2, 0x2, 0x3, 0x7, 0x3, 0x2, 0x4, 0x7, 0x4, + 0x2, 0x5, 0x7, 0x5, 0x2, 0x6, 0x7, 0x6, 0x2, 0x7, 0x7, 0x7, 0x1, + 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, + 0x1, 0x3, 0x1, 0x3, 0x1, 0x4, 0x1, 0x4, 0x5, 0x4, 0x1d, 0x8, 0x4, + 0xa, 0x4, 0xc, 0x4, 0x20, 0x9, 0x4, 0x1, 0x4, 0x1, 0x4, 0x1, 0x5, + 0x1, 0x5, 0x3, 0x5, 0x26, 0x8, 0x5, 0x1, 0x6, 0x1, 0x6, 0x1, 0x7, + 0x1, 0x7, 0x5, 0x7, 0x2c, 0x8, 0x7, 0xa, 0x7, 0xc, 0x7, 0x2f, 0x9, + 0x7, 0x1, 0x7, 0x1, 0x7, 0x1, 0x2d, 0x0, 0x8, 0x1, 0x3, 0x3, 0x4, + 0x5, 0x5, 0x7, 0x6, 0x9, 0x7, 0xb, 0x0, 0xd, 0x0, 0xf, 0x8, 0x1, + 0x0, 0x2, 0x5, 0x0, 0x30, 0x39, 0x5f, 0x5f, 0xb7, 0xb7, 0x300, 0x36f, + 0x203f, 0x2040, 0xd, 0x0, 0x41, 0x5a, 0x61, 0x7a, 0xc0, 0xd6, 0xd8, + 0xf6, 0xf8, 0x2ff, 0x370, 0x37d, 0x37f, 0x1fff, 0x200c, 0x200d, 0x2070, + 0x218f, 0x2c00, 0x2fef, 0x3001, 0xd7ff, 0xf900, 0xfdcf, 0xfdf0, 0xffff, + 0x0, 0x32, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x3, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x5, 0x1, 0x0, 0x0, 0x0, 0x0, 0x7, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x1, 0x0, 0x0, 0x0, 0x0, 0xf, 0x1, 0x0, 0x0, 0x0, 0x1, + 0x11, 0x1, 0x0, 0x0, 0x0, 0x3, 0x14, 0x1, 0x0, 0x0, 0x0, 0x5, 0x16, + 0x1, 0x0, 0x0, 0x0, 0x7, 0x18, 0x1, 0x0, 0x0, 0x0, 0x9, 0x1a, 0x1, + 0x0, 0x0, 0x0, 0xb, 0x25, 0x1, 0x0, 0x0, 0x0, 0xd, 0x27, 0x1, 0x0, + 0x0, 0x0, 0xf, 0x29, 0x1, 0x0, 0x0, 0x0, 0x11, 0x12, 0x5, 0x2f, 0x0, + 0x0, 0x12, 0x13, 0x5, 0x2f, 0x0, 0x0, 0x13, 0x2, 0x1, 0x0, 0x0, 0x0, + 0x14, 0x15, 0x5, 0x2f, 0x0, 0x0, 0x15, 0x4, 0x1, 0x0, 0x0, 0x0, 0x16, + 0x17, 0x5, 0x2a, 0x0, 0x0, 0x17, 0x6, 0x1, 0x0, 0x0, 0x0, 0x18, 0x19, + 0x5, 0x21, 0x0, 0x0, 0x19, 0x8, 0x1, 0x0, 0x0, 0x0, 0x1a, 0x1e, 0x3, + 0xd, 0x6, 0x0, 0x1b, 0x1d, 0x3, 0xb, 0x5, 0x0, 0x1c, 0x1b, 0x1, 0x0, + 0x0, 0x0, 0x1d, 0x20, 0x1, 0x0, 0x0, 0x0, 0x1e, 0x1c, 0x1, 0x0, 0x0, + 0x0, 0x1e, 0x1f, 0x1, 0x0, 0x0, 0x0, 0x1f, 0x21, 0x1, 0x0, 0x0, 0x0, + 0x20, 0x1e, 0x1, 0x0, 0x0, 0x0, 0x21, 0x22, 0x6, 0x4, 0x0, 0x0, 0x22, + 0xa, 0x1, 0x0, 0x0, 0x0, 0x23, 0x26, 0x3, 0xd, 0x6, 0x0, 0x24, 0x26, + 0x7, 0x0, 0x0, 0x0, 0x25, 0x23, 0x1, 0x0, 0x0, 0x0, 0x25, 0x24, 0x1, + 0x0, 0x0, 0x0, 0x26, 0xc, 0x1, 0x0, 0x0, 0x0, 0x27, 0x28, 0x7, 0x1, + 0x0, 0x0, 0x28, 0xe, 0x1, 0x0, 0x0, 0x0, 0x29, 0x2d, 0x5, 0x27, 0x0, + 0x0, 0x2a, 0x2c, 0x9, 0x0, 0x0, 0x0, 0x2b, 0x2a, 0x1, 0x0, 0x0, 0x0, + 0x2c, 0x2f, 0x1, 0x0, 0x0, 0x0, 0x2d, 0x2e, 0x1, 0x0, 0x0, 0x0, 0x2d, + 0x2b, 0x1, 0x0, 0x0, 0x0, 0x2e, 0x30, 0x1, 0x0, 0x0, 0x0, 0x2f, 0x2d, + 0x1, 0x0, 0x0, 0x0, 0x30, 0x31, 0x5, 0x27, 0x0, 0x0, 0x31, 0x10, + 0x1, 0x0, 0x0, 0x0, 0x4, 0x0, 0x1e, 0x25, 0x2d, 0x1, 0x1, 0x4, 0x0, }; _serializedATN.insert(_serializedATN.end(), serializedATNSegment0, @@ -149,12 +149,13 @@ XPathLexer::Initializer::Initializer() { atn::ATNDeserializer deserializer; - _atn = deserializer.deserialize(_serializedATN); + _atn = deserializer.deserialize(_serializedATN).release(); - size_t count = _atn.getNumberOfDecisions(); - _decisionToDFA.reserve(count); - for (size_t i = 0; i < count; i++) { - _decisionToDFA.emplace_back(_atn.getDecisionState(i), i); + size_t count = _atn->getNumberOfDecisions(); + _decisionToDFA = new std::vector(); + _decisionToDFA->reserve(count); + for (size_t i = 0; i < count; i++) { + _decisionToDFA->emplace_back(_atn->getDecisionState(i), i); } } diff --git a/runtime/Cpp/runtime/src/tree/xpath/XPathLexer.h b/runtime/Cpp/runtime/src/tree/xpath/XPathLexer.h index 519e2cbfeb9..0c794b1b40a 100644 --- a/runtime/Cpp/runtime/src/tree/xpath/XPathLexer.h +++ b/runtime/Cpp/runtime/src/tree/xpath/XPathLexer.h @@ -12,7 +12,7 @@ class XPathLexer : public antlr4::Lexer { public: enum { - TOKEN_REF = 1, RULE_REF = 2, ANYWHERE = 3, ROOT = 4, WILDCARD = 5, BANG = 6, + TOKEN_REF = 1, RULE_REF = 2, ANYWHERE = 3, ROOT = 4, WILDCARD = 5, BANG = 6, ID = 7, STRING = 8 }; @@ -26,12 +26,12 @@ class XPathLexer : public antlr4::Lexer { virtual const std::vector& getModeNames() const override; virtual antlr4::dfa::Vocabulary& getVocabulary() const override; - virtual const std::vector getSerializedATN() const override; + virtual const std::vector& getSerializedATN() const override; virtual const antlr4::atn::ATN& getATN() const override; virtual void action(antlr4::RuleContext *context, size_t ruleIndex, size_t actionIndex) override; private: - static std::vector _decisionToDFA; + static std::vector *_decisionToDFA; static antlr4::atn::PredictionContextCache _sharedContextCache; static std::vector _ruleNames; static std::vector _channelNames; @@ -40,7 +40,7 @@ class XPathLexer : public antlr4::Lexer { static std::vector _literalNames; static std::vector _symbolicNames; static antlr4::dfa::Vocabulary _vocabulary; - static antlr4::atn::ATN _atn; + static antlr4::atn::ATN *_atn; static std::vector _serializedATN; 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 5c558fa11f7..3958d565329 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 @@ -74,7 +74,7 @@ public: virtual const std::vector\& getModeNames() const override; virtual antlr4::dfa::Vocabulary& getVocabulary() const override; - virtual const std::vector\ getSerializedATN() const override; + virtual const std::vector\& getSerializedATN() const override; virtual const antlr4::atn::ATN& getATN() const override; @@ -85,7 +85,7 @@ public: private: - static std::vector\ _decisionToDFA; + static std::vector\ *_decisionToDFA; static antlr4::atn::PredictionContextCache _sharedContextCache; static std::vector\ _ruleNames; static std::vector\ _channelNames; @@ -113,7 +113,7 @@ private: Lexer(lexer, atn, actionFuncs, sempredFuncs, superClass = {Lexer}) ::= << ::(CharStream *input) : (input) { - _interpreter = new atn::LexerATNSimulator(this, _atn, _decisionToDFA, _sharedContextCache); + _interpreter = new atn::LexerATNSimulator(this, *_atn, *_decisionToDFA, _sharedContextCache); } ::~() { @@ -140,12 +140,12 @@ dfa::Vocabulary& ::getVocabulary() const { return _vocabulary; } -const std::vector\ ::getSerializedATN() const { +const std::vector\& ::getSerializedATN() const { return _serializedATN; } const atn::ATN& ::getATN() const { - return _atn; + return *_atn; } @@ -178,11 +178,11 @@ bool ::sempred(RuleContext *context, size_t ruleIndex, size_t predic // Static vars and initialization. -std::vector\ ::_decisionToDFA; +std::vector\* ::_decisionToDFA = nullptr; atn::PredictionContextCache ::_sharedContextCache; // We own the ATN which in turn owns the ATN states. -atn::ATN ::_atn; +atn::ATN* ::_atn = nullptr; std::vector\ ::_serializedATN; std::vector\ ::_ruleNames = { @@ -272,7 +272,7 @@ public: ~(); virtual std::string getGrammarFileName() const override; - virtual const antlr4::atn::ATN& getATN() const override { return _atn; }; + virtual const antlr4::atn::ATN& getATN() const override { return *_atn; }; virtual const std::vector\& getRuleNames() const override; virtual antlr4::dfa::Vocabulary& getVocabulary() const override; @@ -288,7 +288,7 @@ public: private: - static std::vector\ _decisionToDFA; + static std::vector\ *_decisionToDFA; static antlr4::atn::PredictionContextCache _sharedContextCache; static std::vector\ _ruleNames; @@ -310,7 +310,7 @@ Parser(parser, funcs, atn, sempredFuncs, superClass = {Parser}) ::= << using namespace antlr4; ::(TokenStream *input) : (input) { - _interpreter = new atn::ParserATNSimulator(this, _atn, _decisionToDFA, _sharedContextCache); + _interpreter = new atn::ParserATNSimulator(this, *_atn, *_decisionToDFA, _sharedContextCache); } ::~() { @@ -348,11 +348,11 @@ bool ::sempred(RuleContext *context, size_t ruleIndex, size_t predi // Static vars and initialization. -std::vector\ ::_decisionToDFA; +std::vector\* ::_decisionToDFA = nullptr; atn::PredictionContextCache ::_sharedContextCache; // We own the ATN which in turn owns the ATN states. -atn::ATN ::_atn; +atn::ATN* ::_atn = nullptr; std::vector\ ::_serializedATN; std::vector\ ::_ruleNames = { @@ -377,7 +377,7 @@ dfa::Vocabulary ::_vocabulary(_literalNames, _symbolicNames); >> SerializedATNHeader(model) ::= << -static antlr4::atn::ATN _atn; +static antlr4::atn::ATN *_atn; static std::vector\ _serializedATN; >> @@ -391,12 +391,13 @@ _serializedATN.insert(_serializedATN.end(), serializedATNSegment, serializedATNSegment + sizeof(serializedATNSegment) / sizeof(serializedATNSegment[0])); atn::ATNDeserializer deserializer; -_atn = deserializer.deserialize(_serializedATN); +_atn = deserializer.deserialize(_serializedATN).release(); -size_t count = _atn.getNumberOfDecisions(); -_decisionToDFA.reserve(count); +size_t count = _atn->getNumberOfDecisions(); +_decisionToDFA = new std::vector\(); +_decisionToDFA->reserve(count); for (size_t i = 0; i \< count; i++) { - _decisionToDFA.emplace_back(_atn.getDecisionState(i), i); + _decisionToDFA->emplace_back(_atn->getDecisionState(i), i); } >>