128 lines
3.0 KiB
C++
128 lines
3.0 KiB
C++
|
|
/* 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<atn::StarLoopEntryState *>(atnStartState)) {
|
|||
|
|
if (static_cast<atn::StarLoopEntryState *>(atnStartState)->isPrecedenceDecision) {
|
|||
|
|
_precedenceDfa = true;
|
|||
|
|
s0 = new DFAState(std::unique_ptr<atn::ATNConfigSet>(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<DFAState *> DFA::getStates() const {
|
|||
|
|
std::vector<DFAState *> 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<std::string> &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();
|
|||
|
|
}
|
|||
|
|
|