]> gitweb.ps.run Git - toc/blobdiff - antlr4-cpp-runtime-4.9.2-source/runtime/src/atn/ATNConfigSet.cpp
add antlr source code and ReadMe
[toc] / antlr4-cpp-runtime-4.9.2-source / runtime / src / atn / ATNConfigSet.cpp
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/atn/ATNConfigSet.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/atn/ATNConfigSet.cpp
new file mode 100644 (file)
index 0000000..7a480a4
--- /dev/null
@@ -0,0 +1,228 @@
+/* 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/PredictionContext.h"
+#include "atn/ATNConfig.h"
+#include "atn/ATNSimulator.h"
+#include "Exceptions.h"
+#include "atn/SemanticContext.h"
+#include "support/Arrays.h"
+
+#include "atn/ATNConfigSet.h"
+
+using namespace antlr4::atn;
+using namespace antlrcpp;
+
+ATNConfigSet::ATNConfigSet(bool fullCtx) : fullCtx(fullCtx) {
+  InitializeInstanceFields();
+}
+
+ATNConfigSet::ATNConfigSet(const Ref<ATNConfigSet> &old) : ATNConfigSet(old->fullCtx) {
+  addAll(old);
+  uniqueAlt = old->uniqueAlt;
+  conflictingAlts = old->conflictingAlts;
+  hasSemanticContext = old->hasSemanticContext;
+  dipsIntoOuterContext = old->dipsIntoOuterContext;
+}
+
+ATNConfigSet::~ATNConfigSet() {
+}
+
+bool ATNConfigSet::add(const Ref<ATNConfig> &config) {
+  return add(config, nullptr);
+}
+
+bool ATNConfigSet::add(const Ref<ATNConfig> &config, PredictionContextMergeCache *mergeCache) {
+  if (_readonly) {
+    throw IllegalStateException("This set is readonly");
+  }
+  if (config->semanticContext != SemanticContext::NONE) {
+    hasSemanticContext = true;
+  }
+  if (config->getOuterContextDepth() > 0) {
+    dipsIntoOuterContext = true;
+  }
+
+  size_t hash = getHash(config.get());
+  ATNConfig *existing = _configLookup[hash];
+  if (existing == nullptr) {
+    _configLookup[hash] = config.get();
+    _cachedHashCode = 0;
+    configs.push_back(config); // track order here
+
+    return true;
+  }
+
+  // a previous (s,i,pi,_), merge with it and save result
+  bool rootIsWildcard = !fullCtx;
+  Ref<PredictionContext> merged = PredictionContext::merge(existing->context, config->context, rootIsWildcard, mergeCache);
+  // no need to check for existing.context, config.context in cache
+  // since only way to create new graphs is "call rule" and here. We
+  // cache at both places.
+  existing->reachesIntoOuterContext = std::max(existing->reachesIntoOuterContext, config->reachesIntoOuterContext);
+
+  // make sure to preserve the precedence filter suppression during the merge
+  if (config->isPrecedenceFilterSuppressed()) {
+    existing->setPrecedenceFilterSuppressed(true);
+  }
+
+  existing->context = merged; // replace context; no need to alt mapping
+
+  return true;
+}
+
+bool ATNConfigSet::addAll(const Ref<ATNConfigSet> &other) {
+  for (auto &c : other->configs) {
+    add(c);
+  }
+  return false;
+}
+
+std::vector<ATNState*> ATNConfigSet::getStates() {
+  std::vector<ATNState*> states;
+  for (auto c : configs) {
+    states.push_back(c->state);
+  }
+  return states;
+}
+
+/**
+ * Gets the complete set of represented alternatives for the configuration
+ * set.
+ *
+ * @return the set of represented alternatives in this configuration set
+ *
+ * @since 4.3
+ */
+
+BitSet ATNConfigSet::getAlts() {
+  BitSet alts;
+  for (ATNConfig config : configs) {
+    alts.set(config.alt);
+  }
+  return alts;
+}
+
+std::vector<Ref<SemanticContext>> ATNConfigSet::getPredicates() {
+  std::vector<Ref<SemanticContext>> preds;
+  for (auto c : configs) {
+    if (c->semanticContext != SemanticContext::NONE) {
+      preds.push_back(c->semanticContext);
+    }
+  }
+  return preds;
+}
+
+Ref<ATNConfig> ATNConfigSet::get(size_t i) const {
+  return configs[i];
+}
+
+void ATNConfigSet::optimizeConfigs(ATNSimulator *interpreter) {
+  if (_readonly) {
+    throw IllegalStateException("This set is readonly");
+  }
+  if (_configLookup.empty())
+    return;
+
+  for (auto &config : configs) {
+    config->context = interpreter->getCachedContext(config->context);
+  }
+}
+
+bool ATNConfigSet::operator == (const ATNConfigSet &other) {
+  if (&other == this) {
+    return true;
+  }
+
+  if (configs.size() != other.configs.size())
+    return false;
+
+  if (fullCtx != other.fullCtx || uniqueAlt != other.uniqueAlt ||
+      conflictingAlts != other.conflictingAlts || hasSemanticContext != other.hasSemanticContext ||
+      dipsIntoOuterContext != other.dipsIntoOuterContext) // includes stack context
+    return false;
+
+  return Arrays::equals(configs, other.configs);
+}
+
+size_t ATNConfigSet::hashCode() {
+  if (!isReadonly() || _cachedHashCode == 0) {
+    _cachedHashCode = 1;
+    for (auto &i : configs) {
+      _cachedHashCode = 31 * _cachedHashCode + i->hashCode(); // Same as Java's list hashCode impl.
+    }
+  }
+
+  return _cachedHashCode;
+}
+
+size_t ATNConfigSet::size() {
+  return configs.size();
+}
+
+bool ATNConfigSet::isEmpty() {
+  return configs.empty();
+}
+
+void ATNConfigSet::clear() {
+  if (_readonly) {
+    throw IllegalStateException("This set is readonly");
+  }
+  configs.clear();
+  _cachedHashCode = 0;
+  _configLookup.clear();
+}
+
+bool ATNConfigSet::isReadonly() {
+  return _readonly;
+}
+
+void ATNConfigSet::setReadonly(bool readonly) {
+  _readonly = readonly;
+  _configLookup.clear();
+}
+
+std::string ATNConfigSet::toString() {
+  std::stringstream ss;
+  ss << "[";
+  for (size_t i = 0; i < configs.size(); i++) {
+    ss << configs[i]->toString();
+  }
+  ss << "]";
+
+  if (hasSemanticContext) {
+    ss << ",hasSemanticContext = " <<  hasSemanticContext;
+  }
+  if (uniqueAlt != ATN::INVALID_ALT_NUMBER) {
+    ss << ",uniqueAlt = " << uniqueAlt;
+  }
+
+  if (conflictingAlts.size() > 0) {
+    ss << ",conflictingAlts = ";
+    ss << conflictingAlts.toString();
+  }
+
+  if (dipsIntoOuterContext) {
+    ss << ", dipsIntoOuterContext";
+  }
+  return ss.str();
+}
+
+size_t ATNConfigSet::getHash(ATNConfig *c) {
+  size_t hashCode = 7;
+  hashCode = 31 * hashCode + c->state->stateNumber;
+  hashCode = 31 * hashCode + c->alt;
+  hashCode = 31 * hashCode + c->semanticContext->hashCode();
+  return hashCode;
+}
+
+void ATNConfigSet::InitializeInstanceFields() {
+  uniqueAlt = 0;
+  hasSemanticContext = false;
+  dipsIntoOuterContext = false;
+
+  _readonly = false;
+  _cachedHashCode = 0;
+}