/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. * Use of this file is governed by the BSD 3-clause license that * can be found in the LICENSE.txt file in the project root. */ #include "dfa/DFASerializer.h" #include "dfa/LexerDFASerializer.h" #include "support/CPPUtils.h" #include "atn/StarLoopEntryState.h" #include "atn/ATNConfigSet.h" #include "dfa/DFA.h" using namespace antlr4; using namespace antlr4::dfa; using namespace antlrcpp; DFA::DFA(atn::DecisionState *atnStartState) : DFA(atnStartState, 0) { } DFA::DFA(atn::DecisionState *atnStartState, size_t decision) : atnStartState(atnStartState), s0(nullptr), decision(decision) { _precedenceDfa = false; if (is(atnStartState)) { if (static_cast(atnStartState)->isPrecedenceDecision) { _precedenceDfa = true; s0 = new DFAState(std::unique_ptr(new atn::ATNConfigSet())); s0->isAcceptState = false; s0->requiresFullContext = false; } } } DFA::DFA(DFA &&other) : atnStartState(other.atnStartState), decision(other.decision) { // Source states are implicitly cleared by the move. states = std::move(other.states); other.atnStartState = nullptr; other.decision = 0; s0 = other.s0; other.s0 = nullptr; _precedenceDfa = other._precedenceDfa; other._precedenceDfa = false; } DFA::~DFA() { bool s0InList = (s0 == nullptr); for (auto *state : states) { if (state == s0) s0InList = true; delete state; } if (!s0InList) delete s0; } bool DFA::isPrecedenceDfa() const { return _precedenceDfa; } DFAState* DFA::getPrecedenceStartState(int precedence) const { assert(_precedenceDfa); // Only precedence DFAs may contain a precedence start state. auto iterator = s0->edges.find(precedence); if (iterator == s0->edges.end()) return nullptr; return iterator->second; } void DFA::setPrecedenceStartState(int precedence, DFAState *startState, SingleWriteMultipleReadLock &lock) { if (!isPrecedenceDfa()) { throw IllegalStateException("Only precedence DFAs may contain a precedence start state."); } if (precedence < 0) { return; } { lock.writeLock(); s0->edges[precedence] = startState; lock.writeUnlock(); } } std::vector DFA::getStates() const { std::vector result; for (auto *state : states) result.push_back(state); std::sort(result.begin(), result.end(), [](DFAState *o1, DFAState *o2) -> bool { return o1->stateNumber < o2->stateNumber; }); return result; } std::string DFA::toString(const std::vector &tokenNames) { if (s0 == nullptr) { return ""; } DFASerializer serializer(this, tokenNames); return serializer.toString(); } std::string DFA::toString(const Vocabulary &vocabulary) const { if (s0 == nullptr) { return ""; } DFASerializer serializer(this, vocabulary); return serializer.toString(); } std::string DFA::toLexerString() { if (s0 == nullptr) { return ""; } LexerDFASerializer serializer(this); return serializer.toString(); }