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.
6 #include "atn/LL1Analyzer.h"
8 #include "atn/RuleTransition.h"
9 #include "misc/IntervalSet.h"
10 #include "RuleContext.h"
11 #include "atn/DecisionState.h"
12 #include "Recognizer.h"
13 #include "atn/ATNType.h"
14 #include "Exceptions.h"
15 #include "support/CPPUtils.h"
19 using namespace antlr4;
20 using namespace antlr4::atn;
21 using namespace antlrcpp;
23 ATN::ATN() : ATN(ATNType::LEXER, 0) {
26 ATN::ATN(ATN &&other) {
27 // All source vectors are implicitly cleared by the moves.
28 states = std::move(other.states);
29 decisionToState = std::move(other.decisionToState);
30 ruleToStartState = std::move(other.ruleToStartState);
31 ruleToStopState = std::move(other.ruleToStopState);
32 grammarType = std::move(other.grammarType);
33 maxTokenType = std::move(other.maxTokenType);
34 ruleToTokenType = std::move(other.ruleToTokenType);
35 lexerActions = std::move(other.lexerActions);
36 modeToStartState = std::move(other.modeToStartState);
39 ATN::ATN(ATNType grammarType_, size_t maxTokenType_) : grammarType(grammarType_), maxTokenType(maxTokenType_) {
43 for (ATNState *state : states) {
49 * Required to be defined (even though not used) as we have an explicit move assignment operator.
51 ATN& ATN::operator = (ATN &other) NOEXCEPT {
52 states = other.states;
53 decisionToState = other.decisionToState;
54 ruleToStartState = other.ruleToStartState;
55 ruleToStopState = other.ruleToStopState;
56 grammarType = other.grammarType;
57 maxTokenType = other.maxTokenType;
58 ruleToTokenType = other.ruleToTokenType;
59 lexerActions = other.lexerActions;
60 modeToStartState = other.modeToStartState;
66 * Explicit move assignment operator to make this the preferred assignment. With implicit copy/move assignment
67 * operators it seems the copy operator is preferred causing trouble when releasing the allocated ATNState instances.
69 ATN& ATN::operator = (ATN &&other) NOEXCEPT {
70 // All source vectors are implicitly cleared by the moves.
71 states = std::move(other.states);
72 decisionToState = std::move(other.decisionToState);
73 ruleToStartState = std::move(other.ruleToStartState);
74 ruleToStopState = std::move(other.ruleToStopState);
75 grammarType = std::move(other.grammarType);
76 maxTokenType = std::move(other.maxTokenType);
77 ruleToTokenType = std::move(other.ruleToTokenType);
78 lexerActions = std::move(other.lexerActions);
79 modeToStartState = std::move(other.modeToStartState);
84 misc::IntervalSet ATN::nextTokens(ATNState *s, RuleContext *ctx) const {
85 LL1Analyzer analyzer(*this);
86 return analyzer.LOOK(s, ctx);
90 misc::IntervalSet const& ATN::nextTokens(ATNState *s) const {
91 if (!s->_nextTokenUpdated) {
92 std::unique_lock<std::mutex> lock { _mutex };
93 if (!s->_nextTokenUpdated) {
94 s->_nextTokenWithinRule = nextTokens(s, nullptr);
95 s->_nextTokenUpdated = true;
98 return s->_nextTokenWithinRule;
101 void ATN::addState(ATNState *state) {
102 if (state != nullptr) {
104 state->stateNumber = static_cast<int>(states.size());
107 states.push_back(state);
110 void ATN::removeState(ATNState *state) {
111 delete states.at(state->stateNumber);// just free mem, don't shift states in list
112 states.at(state->stateNumber) = nullptr;
115 int ATN::defineDecisionState(DecisionState *s) {
116 decisionToState.push_back(s);
117 s->decision = static_cast<int>(decisionToState.size() - 1);
121 DecisionState *ATN::getDecisionState(size_t decision) const {
122 if (!decisionToState.empty()) {
123 return decisionToState[decision];
128 size_t ATN::getNumberOfDecisions() const {
129 return decisionToState.size();
132 misc::IntervalSet ATN::getExpectedTokens(size_t stateNumber, RuleContext *context) const {
133 if (stateNumber == ATNState::INVALID_STATE_NUMBER || stateNumber >= states.size()) {
134 throw IllegalArgumentException("Invalid state number.");
137 RuleContext *ctx = context;
138 ATNState *s = states.at(stateNumber);
139 misc::IntervalSet following = nextTokens(s);
140 if (!following.contains(Token::EPSILON)) {
144 misc::IntervalSet expected;
145 expected.addAll(following);
146 expected.remove(Token::EPSILON);
147 while (ctx && ctx->invokingState != ATNState::INVALID_STATE_NUMBER && following.contains(Token::EPSILON)) {
148 ATNState *invokingState = states.at(ctx->invokingState);
149 RuleTransition *rt = static_cast<RuleTransition*>(invokingState->transitions[0]);
150 following = nextTokens(rt->followState);
151 expected.addAll(following);
152 expected.remove(Token::EPSILON);
154 if (ctx->parent == nullptr) {
157 ctx = static_cast<RuleContext *>(ctx->parent);
160 if (following.contains(Token::EPSILON)) {
161 expected.add(Token::EOF);
167 std::string ATN::toString() const {
168 std::stringstream ss;
170 switch (grammarType) {
175 case ATNType::PARSER:
182 ss << "(" << type << "ATN " << std::hex << this << std::dec << ") maxTokenType: " << maxTokenType << std::endl;
183 ss << "states (" << states.size() << ") {" << std::endl;
186 for (auto *state : states) {
187 if (state == nullptr) {
188 ss << " " << index++ << ": nul" << std::endl;
190 std::string text = state->toString();
191 ss << " " << index++ << ": " << indent(text, " ", false) << std::endl;
196 for (auto *state : decisionToState) {
197 if (state == nullptr) {
198 ss << " " << index++ << ": nul" << std::endl;
200 std::string text = state->toString();
201 ss << " " << index++ << ": " << indent(text, " ", false) << std::endl;