blob: 66a91936e91c2fc7533150e8e61de6eb5f104efb (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
/* 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/SingletonPredictionContext.h"
#include "support/Casts.h"
#include "misc/MurmurHash.h"
using namespace antlr4::atn;
using namespace antlrcpp;
namespace {
bool cachedHashCodeEqual(size_t lhs, size_t rhs) {
return lhs == rhs || lhs == 0 || rhs == 0;
}
}
SingletonPredictionContext::SingletonPredictionContext(Ref<const PredictionContext> parent, size_t returnState)
: PredictionContext(PredictionContextType::SINGLETON), parent(std::move(parent)), returnState(returnState) {
assert(returnState != ATNState::INVALID_STATE_NUMBER);
}
Ref<const SingletonPredictionContext> SingletonPredictionContext::create(Ref<const PredictionContext> parent, size_t returnState) {
if (returnState == EMPTY_RETURN_STATE && parent == nullptr) {
// someone can pass in the bits of an array ctx that mean $
return std::dynamic_pointer_cast<const SingletonPredictionContext>(EMPTY);
}
return std::make_shared<SingletonPredictionContext>(std::move(parent), returnState);
}
bool SingletonPredictionContext::isEmpty() const {
return parent == nullptr && returnState == EMPTY_RETURN_STATE;
}
size_t SingletonPredictionContext::size() const {
return 1;
}
const Ref<const PredictionContext>& SingletonPredictionContext::getParent(size_t index) const {
assert(index == 0);
static_cast<void>(index);
return parent;
}
size_t SingletonPredictionContext::getReturnState(size_t index) const {
assert(index == 0);
static_cast<void>(index);
return returnState;
}
size_t SingletonPredictionContext::hashCodeImpl() const {
size_t hash = misc::MurmurHash::initialize();
hash = misc::MurmurHash::update(hash, static_cast<size_t>(getContextType()));
hash = misc::MurmurHash::update(hash, parent);
hash = misc::MurmurHash::update(hash, returnState);
return misc::MurmurHash::finish(hash, 3);
}
bool SingletonPredictionContext::equals(const PredictionContext &other) const {
if (this == std::addressof(other)) {
return true;
}
if (getContextType() != other.getContextType()) {
return false;
}
const auto &singleton = downCast<const SingletonPredictionContext&>(other);
return returnState == singleton.returnState &&
cachedHashCodeEqual(cachedHashCode(), singleton.cachedHashCode()) &&
(parent == singleton.parent || (parent != nullptr && singleton.parent != nullptr && *parent == *singleton.parent));
}
std::string SingletonPredictionContext::toString() const {
//std::string up = !parent.expired() ? parent.lock()->toString() : "";
std::string up = parent != nullptr ? parent->toString() : "";
if (up.length() == 0) {
if (returnState == EMPTY_RETURN_STATE) {
return "$";
}
return std::to_string(returnState);
}
return std::to_string(returnState) + " " + up;
}
|