]> gitweb.ps.run Git - toc/blob - antlr4-cpp-runtime-4.9.2-source/runtime/src/dfa/DFA.cpp
add antlr source code and ReadMe
[toc] / antlr4-cpp-runtime-4.9.2-source / runtime / src / dfa / DFA.cpp
1 /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
2  * Use of this file is governed by the BSD 3-clause license that
3  * can be found in the LICENSE.txt file in the project root.
4  */
5
6 #include "dfa/DFASerializer.h"
7 #include "dfa/LexerDFASerializer.h"
8 #include "support/CPPUtils.h"
9 #include "atn/StarLoopEntryState.h"
10 #include "atn/ATNConfigSet.h"
11
12 #include "dfa/DFA.h"
13
14 using namespace antlr4;
15 using namespace antlr4::dfa;
16 using namespace antlrcpp;
17
18 DFA::DFA(atn::DecisionState *atnStartState) : DFA(atnStartState, 0) {
19 }
20
21 DFA::DFA(atn::DecisionState *atnStartState, size_t decision)
22   : atnStartState(atnStartState), s0(nullptr), decision(decision) {
23
24   _precedenceDfa = false;
25   if (is<atn::StarLoopEntryState *>(atnStartState)) {
26     if (static_cast<atn::StarLoopEntryState *>(atnStartState)->isPrecedenceDecision) {
27       _precedenceDfa = true;
28       s0 = new DFAState(std::unique_ptr<atn::ATNConfigSet>(new atn::ATNConfigSet()));
29       s0->isAcceptState = false;
30       s0->requiresFullContext = false;
31     }
32   }
33 }
34
35 DFA::DFA(DFA &&other) : atnStartState(other.atnStartState), decision(other.decision) {
36   // Source states are implicitly cleared by the move.
37   states = std::move(other.states);
38
39   other.atnStartState = nullptr;
40   other.decision = 0;
41   s0 = other.s0;
42   other.s0 = nullptr;
43   _precedenceDfa = other._precedenceDfa;
44   other._precedenceDfa = false;
45 }
46
47 DFA::~DFA() {
48   bool s0InList = (s0 == nullptr);
49   for (auto *state : states) {
50     if (state == s0)
51       s0InList = true;
52     delete state;
53   }
54
55   if (!s0InList)
56     delete s0;
57 }
58
59 bool DFA::isPrecedenceDfa() const {
60   return _precedenceDfa;
61 }
62
63 DFAState* DFA::getPrecedenceStartState(int precedence) const {
64   assert(_precedenceDfa); // Only precedence DFAs may contain a precedence start state.
65
66   auto iterator = s0->edges.find(precedence);
67   if (iterator == s0->edges.end())
68     return nullptr;
69
70   return iterator->second;
71 }
72
73 void DFA::setPrecedenceStartState(int precedence, DFAState *startState, SingleWriteMultipleReadLock &lock) {
74   if (!isPrecedenceDfa()) {
75     throw IllegalStateException("Only precedence DFAs may contain a precedence start state.");
76   }
77
78   if (precedence < 0) {
79     return;
80   }
81
82   {
83     lock.writeLock();
84     s0->edges[precedence] = startState;
85     lock.writeUnlock();
86   }
87 }
88
89 std::vector<DFAState *> DFA::getStates() const {
90   std::vector<DFAState *> result;
91   for (auto *state : states)
92     result.push_back(state);
93
94   std::sort(result.begin(), result.end(), [](DFAState *o1, DFAState *o2) -> bool {
95     return o1->stateNumber < o2->stateNumber;
96   });
97
98   return result;
99 }
100
101 std::string DFA::toString(const std::vector<std::string> &tokenNames) {
102   if (s0 == nullptr) {
103     return "";
104   }
105   DFASerializer serializer(this, tokenNames);
106
107   return serializer.toString();
108 }
109
110 std::string DFA::toString(const Vocabulary &vocabulary) const {
111   if (s0 == nullptr) {
112     return "";
113   }
114
115   DFASerializer serializer(this, vocabulary);
116   return serializer.toString();
117 }
118
119 std::string DFA::toLexerString() {
120   if (s0 == nullptr) {
121     return "";
122   }
123   LexerDFASerializer serializer(this);
124
125   return serializer.toString();
126 }
127