]> gitweb.ps.run Git - toc/blobdiff - antlr4-cpp-runtime-4.9.2-source/runtime/src/atn/ATN.cpp
add antlr source code and ReadMe
[toc] / antlr4-cpp-runtime-4.9.2-source / runtime / src / atn / ATN.cpp
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/atn/ATN.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/atn/ATN.cpp
new file mode 100644 (file)
index 0000000..2334e6b
--- /dev/null
@@ -0,0 +1,209 @@
+/* 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 "atn/LL1Analyzer.h"
+#include "Token.h"
+#include "atn/RuleTransition.h"
+#include "misc/IntervalSet.h"
+#include "RuleContext.h"
+#include "atn/DecisionState.h"
+#include "Recognizer.h"
+#include "atn/ATNType.h"
+#include "Exceptions.h"
+#include "support/CPPUtils.h"
+
+#include "atn/ATN.h"
+
+using namespace antlr4;
+using namespace antlr4::atn;
+using namespace antlrcpp;
+
+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() {
+  for (ATNState *state : states) {
+    delete state;
+  }
+}
+
+/**
+ * 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);
+
+}
+
+misc::IntervalSet const& ATN::nextTokens(ATNState *s) const {
+  if (!s->_nextTokenUpdated) {
+    std::unique_lock<std::mutex> lock { _mutex };
+    if (!s->_nextTokenUpdated) {
+      s->_nextTokenWithinRule = nextTokens(s, nullptr);
+      s->_nextTokenUpdated = true;
+    }
+  }
+  return s->_nextTokenWithinRule;
+}
+
+void ATN::addState(ATNState *state) {
+  if (state != nullptr) {
+    //state->atn = this;
+    state->stateNumber = static_cast<int>(states.size());
+  }
+
+  states.push_back(state);
+}
+
+void ATN::removeState(ATNState *state) {
+  delete states.at(state->stateNumber);// just free mem, don't shift states in list
+  states.at(state->stateNumber) = nullptr;
+}
+
+int ATN::defineDecisionState(DecisionState *s) {
+  decisionToState.push_back(s);
+  s->decision = static_cast<int>(decisionToState.size() - 1);
+  return s->decision;
+}
+
+DecisionState *ATN::getDecisionState(size_t decision) const {
+  if (!decisionToState.empty()) {
+    return decisionToState[decision];
+  }
+  return nullptr;
+}
+
+size_t ATN::getNumberOfDecisions() const {
+  return decisionToState.size();
+}
+
+misc::IntervalSet ATN::getExpectedTokens(size_t stateNumber, RuleContext *context) const {
+  if (stateNumber == ATNState::INVALID_STATE_NUMBER || stateNumber >= states.size()) {
+    throw IllegalArgumentException("Invalid state number.");
+  }
+
+  RuleContext *ctx = context;
+  ATNState *s = states.at(stateNumber);
+  misc::IntervalSet following = nextTokens(s);
+  if (!following.contains(Token::EPSILON)) {
+    return following;
+  }
+
+  misc::IntervalSet expected;
+  expected.addAll(following);
+  expected.remove(Token::EPSILON);
+  while (ctx && ctx->invokingState != ATNState::INVALID_STATE_NUMBER && following.contains(Token::EPSILON)) {
+    ATNState *invokingState = states.at(ctx->invokingState);
+    RuleTransition *rt = static_cast<RuleTransition*>(invokingState->transitions[0]);
+    following = nextTokens(rt->followState);
+    expected.addAll(following);
+    expected.remove(Token::EPSILON);
+
+    if (ctx->parent == nullptr) {
+      break;
+    }
+    ctx = static_cast<RuleContext *>(ctx->parent);
+  }
+
+  if (following.contains(Token::EPSILON)) {
+    expected.add(Token::EOF);
+  }
+
+  return expected;
+}
+
+std::string ATN::toString() const {
+  std::stringstream ss;
+  std::string type;
+  switch (grammarType) {
+    case ATNType::LEXER:
+      type = "LEXER ";
+      break;
+
+    case ATNType::PARSER:
+      type = "PARSER ";
+      break;
+
+    default:
+      break;
+  }
+  ss << "(" << type << "ATN " << std::hex << this << std::dec << ") maxTokenType: " << maxTokenType << std::endl;
+  ss << "states (" << states.size() << ") {" << std::endl;
+
+  size_t index = 0;
+  for (auto *state : states) {
+    if (state == nullptr) {
+      ss << "  " << index++ << ": nul" << std::endl;
+    } else {
+      std::string text = state->toString();
+      ss << "  " << index++ << ": " << indent(text, "  ", false) << std::endl;
+    }
+  }
+
+  index = 0;
+  for (auto *state : decisionToState) {
+    if (state == nullptr) {
+      ss << "  " << index++ << ": nul" << std::endl;
+    } else {
+      std::string text = state->toString();
+      ss << "  " << index++ << ": " << indent(text, "  ", false) << std::endl;
+    }
+  }
+
+  ss << "}";
+
+  return ss.str();
+}
+