context;
+
+ /**
+ * We cannot execute predicates dependent upon local context unless
+ * we know for sure we are in the correct context. Because there is
+ * no way to do this efficiently, we simply cannot evaluate
+ * dependent predicates unless we are in the rule that initially
+ * invokes the ATN simulator.
+ *
+ *
+ * closure() tracks the depth of how far we dip into the outer context:
+ * depth > 0. Note that it may not be totally accurate depth since I
+ * don't ever decrement. TODO: make it a boolean then
+ *
+ *
+ * For memory efficiency, the {@link #isPrecedenceFilterSuppressed} method
+ * is also backed by this field. Since the field is publicly accessible, the
+ * highest bit which would not cause the value to become negative is used to
+ * store this field. This choice minimizes the risk that code which only
+ * compares this value to 0 would be affected by the new purpose of the
+ * flag. It also ensures the performance of the existing {@link ATNConfig}
+ * constructors as well as certain operations like
+ * {@link ATNConfigSet#add(ATNConfig, DoubleKeyMap)} method are
+ * completely unaffected by the change.
+ */
+ size_t reachesIntoOuterContext;
+
+ /// Can be shared between multiple ATNConfig instances.
+ Ref semanticContext;
+
+ ATNConfig(ATNState *state, size_t alt, Ref const& context);
+ ATNConfig(ATNState *state, size_t alt, Ref const& context, Ref const& semanticContext);
+
+ ATNConfig(Ref const& c); // dup
+ ATNConfig(Ref const& c, ATNState *state);
+ ATNConfig(Ref const& c, ATNState *state, Ref const& semanticContext);
+ ATNConfig(Ref const& c, Ref const& semanticContext);
+ ATNConfig(Ref const& c, ATNState *state, Ref const& context);
+ ATNConfig(Ref const& c, ATNState *state, Ref const& context, Ref const& semanticContext);
+
+ ATNConfig(ATNConfig const&) = default;
+ virtual ~ATNConfig();
+
+ virtual size_t hashCode() const;
+
+ /**
+ * This method gets the value of the {@link #reachesIntoOuterContext} field
+ * as it existed prior to the introduction of the
+ * {@link #isPrecedenceFilterSuppressed} method.
+ */
+ size_t getOuterContextDepth() const ;
+ bool isPrecedenceFilterSuppressed() const;
+ void setPrecedenceFilterSuppressed(bool value);
+
+ /// An ATN configuration is equal to another if both have
+ /// the same state, they predict the same alternative, and
+ /// syntactic/semantic contexts are the same.
+ bool operator == (const ATNConfig &other) const;
+ bool operator != (const ATNConfig &other) const;
+
+ virtual std::string toString();
+ std::string toString(bool showAlt);
+
+ private:
+ /**
+ * This field stores the bit mask for implementing the
+ * {@link #isPrecedenceFilterSuppressed} property as a bit within the
+ * existing {@link #reachesIntoOuterContext} field.
+ */
+#if __cplusplus >= 201703L
+ static constexpr size_t SUPPRESS_PRECEDENCE_FILTER = 0x40000000;
+#else
+ enum : size_t {
+ SUPPRESS_PRECEDENCE_FILTER = 0x40000000,
+ };
+#endif
+ };
+
+} // namespace atn
+} // namespace antlr4
+
+
+// Hash function for ATNConfig.
+
+namespace std {
+ using antlr4::atn::ATNConfig;
+
+ template <> struct hash
+ {
+ size_t operator() (const ATNConfig &x) const
+ {
+ return x.hashCode();
+ }
+ };
+
+ template <> struct hash>>
+ {
+ size_t operator() (const std::vector[> &vector) const
+ {
+ std::size_t seed = 0;
+ for (const auto &config : vector) {
+ seed ^= config->hashCode() + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+ }
+ return seed;
+ }
+ };
+}
]