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.
12 /// A tuple: (ATN state, predicted alt, syntactic, semantic context).
13 /// The syntactic context is a graph-structured stack node whose
14 /// path(s) to the root is the rule invocation(s)
15 /// chain used to arrive at the state. The semantic context is
16 /// the tree of semantic predicates encountered before reaching
19 class ANTLR4CPP_PUBLIC ATNConfig {
23 size_t operator()(ATNConfig const& k) const {
29 bool operator()(ATNConfig const& lhs, ATNConfig const& rhs) const {
30 return (&lhs == &rhs) || (lhs == rhs);
35 using Set = std::unordered_set<Ref<ATNConfig>, Hasher, Comparer>;
37 /// The ATN state associated with this configuration.
40 /// What alt (or lexer rule) is predicted by this configuration.
43 /// The stack of invoking states leading to the rule/states associated
44 /// with this config. We track only those contexts pushed during
45 /// execution of the ATN simulator.
47 /// Can be shared between multiple ANTConfig instances.
48 Ref<PredictionContext> context;
51 * We cannot execute predicates dependent upon local context unless
52 * we know for sure we are in the correct context. Because there is
53 * no way to do this efficiently, we simply cannot evaluate
54 * dependent predicates unless we are in the rule that initially
55 * invokes the ATN simulator.
58 * closure() tracks the depth of how far we dip into the outer context:
59 * depth > 0. Note that it may not be totally accurate depth since I
60 * don't ever decrement. TODO: make it a boolean then</p>
63 * For memory efficiency, the {@link #isPrecedenceFilterSuppressed} method
64 * is also backed by this field. Since the field is publicly accessible, the
65 * highest bit which would not cause the value to become negative is used to
66 * store this field. This choice minimizes the risk that code which only
67 * compares this value to 0 would be affected by the new purpose of the
68 * flag. It also ensures the performance of the existing {@link ATNConfig}
69 * constructors as well as certain operations like
70 * {@link ATNConfigSet#add(ATNConfig, DoubleKeyMap)} method are
71 * <em>completely</em> unaffected by the change.</p>
73 size_t reachesIntoOuterContext;
75 /// Can be shared between multiple ATNConfig instances.
76 Ref<SemanticContext> semanticContext;
78 ATNConfig(ATNState *state, size_t alt, Ref<PredictionContext> const& context);
79 ATNConfig(ATNState *state, size_t alt, Ref<PredictionContext> const& context, Ref<SemanticContext> const& semanticContext);
81 ATNConfig(Ref<ATNConfig> const& c); // dup
82 ATNConfig(Ref<ATNConfig> const& c, ATNState *state);
83 ATNConfig(Ref<ATNConfig> const& c, ATNState *state, Ref<SemanticContext> const& semanticContext);
84 ATNConfig(Ref<ATNConfig> const& c, Ref<SemanticContext> const& semanticContext);
85 ATNConfig(Ref<ATNConfig> const& c, ATNState *state, Ref<PredictionContext> const& context);
86 ATNConfig(Ref<ATNConfig> const& c, ATNState *state, Ref<PredictionContext> const& context, Ref<SemanticContext> const& semanticContext);
88 ATNConfig(ATNConfig const&) = default;
91 virtual size_t hashCode() const;
94 * This method gets the value of the {@link #reachesIntoOuterContext} field
95 * as it existed prior to the introduction of the
96 * {@link #isPrecedenceFilterSuppressed} method.
98 size_t getOuterContextDepth() const ;
99 bool isPrecedenceFilterSuppressed() const;
100 void setPrecedenceFilterSuppressed(bool value);
102 /// An ATN configuration is equal to another if both have
103 /// the same state, they predict the same alternative, and
104 /// syntactic/semantic contexts are the same.
105 bool operator == (const ATNConfig &other) const;
106 bool operator != (const ATNConfig &other) const;
108 virtual std::string toString();
109 std::string toString(bool showAlt);
113 * This field stores the bit mask for implementing the
114 * {@link #isPrecedenceFilterSuppressed} property as a bit within the
115 * existing {@link #reachesIntoOuterContext} field.
117 #if __cplusplus >= 201703L
118 static constexpr size_t SUPPRESS_PRECEDENCE_FILTER = 0x40000000;
121 SUPPRESS_PRECEDENCE_FILTER = 0x40000000,
127 } // namespace antlr4
130 // Hash function for ATNConfig.
133 using antlr4::atn::ATNConfig;
135 template <> struct hash<ATNConfig>
137 size_t operator() (const ATNConfig &x) const
143 template <> struct hash<std::vector<Ref<ATNConfig>>>
145 size_t operator() (const std::vector<Ref<ATNConfig>> &vector) const
147 std::size_t seed = 0;
148 for (const auto &config : vector) {
149 seed ^= config->hashCode() + 0x9e3779b9 + (seed << 6) + (seed >> 2);