diff options
| author | asmyasnikov <[email protected]> | 2024-06-26 17:09:51 +0300 |
|---|---|---|
| committer | asmyasnikov <[email protected]> | 2024-06-26 17:27:07 +0300 |
| commit | e25934f4bbe7b98daa362f04861972e8f83066ad (patch) | |
| tree | b350932f398fafa6740fe43a529edf700c747270 /contrib/libs/antlr4_cpp_runtime/src/atn/ArrayPredictionContext.cpp | |
| parent | e6190f5d36aef50e2fec0076c384ba0874f5564c (diff) | |
Added antlr4 to exported contribs into github.com/ydb-platform/ydb
4916444b182c044b7cd4c10f838a37a252ea36cf
Diffstat (limited to 'contrib/libs/antlr4_cpp_runtime/src/atn/ArrayPredictionContext.cpp')
| -rw-r--r-- | contrib/libs/antlr4_cpp_runtime/src/atn/ArrayPredictionContext.cpp | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/contrib/libs/antlr4_cpp_runtime/src/atn/ArrayPredictionContext.cpp b/contrib/libs/antlr4_cpp_runtime/src/atn/ArrayPredictionContext.cpp new file mode 100644 index 00000000000..e9478001b45 --- /dev/null +++ b/contrib/libs/antlr4_cpp_runtime/src/atn/ArrayPredictionContext.cpp @@ -0,0 +1,109 @@ +/* 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/ArrayPredictionContext.h" + +#include <cstring> + +#include "atn/SingletonPredictionContext.h" +#include "misc/MurmurHash.h" +#include "support/Casts.h" + +using namespace antlr4::atn; +using namespace antlr4::misc; +using namespace antlrcpp; + +namespace { + + bool cachedHashCodeEqual(size_t lhs, size_t rhs) { + return lhs == rhs || lhs == 0 || rhs == 0; + } + + bool predictionContextEqual(const Ref<const PredictionContext> &lhs, const Ref<const PredictionContext> &rhs) { + return *lhs == *rhs; + } + +} + +ArrayPredictionContext::ArrayPredictionContext(const SingletonPredictionContext &predictionContext) + : ArrayPredictionContext({ predictionContext.parent }, { predictionContext.returnState }) {} + +ArrayPredictionContext::ArrayPredictionContext(std::vector<Ref<const PredictionContext>> parents, + std::vector<size_t> returnStates) + : PredictionContext(PredictionContextType::ARRAY), parents(std::move(parents)), returnStates(std::move(returnStates)) { + assert(this->parents.size() > 0); + assert(this->returnStates.size() > 0); + assert(this->parents.size() == this->returnStates.size()); +} + +bool ArrayPredictionContext::isEmpty() const { + // Since EMPTY_RETURN_STATE can only appear in the last position, we don't need to verify that size == 1. + return returnStates[0] == EMPTY_RETURN_STATE; +} + +size_t ArrayPredictionContext::size() const { + return returnStates.size(); +} + +const Ref<const PredictionContext>& ArrayPredictionContext::getParent(size_t index) const { + return parents[index]; +} + +size_t ArrayPredictionContext::getReturnState(size_t index) const { + return returnStates[index]; +} + +size_t ArrayPredictionContext::hashCodeImpl() const { + size_t hash = MurmurHash::initialize(); + hash = MurmurHash::update(hash, static_cast<size_t>(getContextType())); + for (const auto &parent : parents) { + hash = MurmurHash::update(hash, parent); + } + for (const auto &returnState : returnStates) { + hash = MurmurHash::update(hash, returnState); + } + return MurmurHash::finish(hash, 1 + parents.size() + returnStates.size()); +} + +bool ArrayPredictionContext::equals(const PredictionContext &other) const { + if (this == std::addressof(other)) { + return true; + } + if (getContextType() != other.getContextType()) { + return false; + } + const auto &array = downCast<const ArrayPredictionContext&>(other); + return returnStates.size() == array.returnStates.size() && + parents.size() == array.parents.size() && + cachedHashCodeEqual(cachedHashCode(), array.cachedHashCode()) && + std::memcmp(returnStates.data(), array.returnStates.data(), returnStates.size() * sizeof(decltype(returnStates)::value_type)) == 0 && + std::equal(parents.begin(), parents.end(), array.parents.begin(), predictionContextEqual); +} + +std::string ArrayPredictionContext::toString() const { + if (isEmpty()) { + return "[]"; + } + + std::stringstream ss; + ss << "["; + for (size_t i = 0; i < returnStates.size(); i++) { + if (i > 0) { + ss << ", "; + } + if (returnStates[i] == EMPTY_RETURN_STATE) { + ss << "$"; + continue; + } + ss << returnStates[i]; + if (parents[i] != nullptr) { + ss << " " << parents[i]->toString(); + } else { + ss << "nul"; + } + } + ss << "]"; + return ss.str(); +} |
