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.
8 #include "Recognizer.h"
9 #include "support/CPPUtils.h"
14 /// A tree structure used to record the semantic context in which
15 /// an ATN configuration is valid. It's either a single predicate,
16 /// a conjunction "p1 && p2", or a sum of products "p1||p2".
18 /// I have scoped the AND, OR, and Predicate subclasses of
19 /// SemanticContext within the scope of this outer class.
20 class ANTLR4CPP_PUBLIC SemanticContext : public std::enable_shared_from_this<SemanticContext> {
24 size_t operator()(Ref<SemanticContext> const& k) const {
30 bool operator()(Ref<SemanticContext> const& lhs, Ref<SemanticContext> const& rhs) const {
33 return (lhs->hashCode() == rhs->hashCode()) && (*lhs == *rhs);
38 using Set = std::unordered_set<Ref<SemanticContext>, Hasher, Comparer>;
41 * The default {@link SemanticContext}, which is semantically equivalent to
42 * a predicate of the form {@code {true}?}.
44 static const Ref<SemanticContext> NONE;
46 virtual ~SemanticContext();
48 virtual size_t hashCode() const = 0;
49 virtual std::string toString() const = 0;
50 virtual bool operator == (const SemanticContext &other) const = 0;
51 virtual bool operator != (const SemanticContext &other) const;
54 /// For context independent predicates, we evaluate them without a local
55 /// context (i.e., null context). That way, we can evaluate them without
56 /// having to create proper rule-specific context during prediction (as
57 /// opposed to the parser, which creates them naturally). In a practical
58 /// sense, this avoids a cast exception from RuleContext to myruleContext.
60 /// For context dependent predicates, we must pass in a local context so that
61 /// references such as $arg evaluate properly as _localctx.arg. We only
62 /// capture context dependent predicates in the context in which we begin
63 /// prediction, so we passed in the outer context here in case of context
64 /// dependent predicate evaluation.
66 virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) = 0;
69 * Evaluate the precedence predicates for the context and reduce the result.
71 * @param parser The parser instance.
72 * @param parserCallStack
73 * @return The simplified semantic context after precedence predicates are
74 * evaluated, which will be one of the following values.
76 * <li>{@link #NONE}: if the predicate simplifies to {@code true} after
77 * precedence predicates are evaluated.</li>
78 * <li>{@code null}: if the predicate simplifies to {@code false} after
79 * precedence predicates are evaluated.</li>
80 * <li>{@code this}: if the semantic context is not changed as a result of
81 * precedence predicate evaluation.</li>
82 * <li>A non-{@code null} {@link SemanticContext}: the new simplified
83 * semantic context after precedence predicates are evaluated.</li>
86 virtual Ref<SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack);
88 static Ref<SemanticContext> And(Ref<SemanticContext> const& a, Ref<SemanticContext> const& b);
90 /// See also: ParserATNSimulator::getPredsForAmbigAlts.
91 static Ref<SemanticContext> Or(Ref<SemanticContext> const& a, Ref<SemanticContext> const& b);
94 class PrecedencePredicate;
100 static std::vector<Ref<PrecedencePredicate>> filterPrecedencePredicates(const Set &collection);
103 class ANTLR4CPP_PUBLIC SemanticContext::Predicate : public SemanticContext {
105 const size_t ruleIndex;
106 const size_t predIndex;
107 const bool isCtxDependent; // e.g., $i ref in pred
113 Predicate(size_t ruleIndex, size_t predIndex, bool isCtxDependent);
115 virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) override;
116 virtual size_t hashCode() const override;
117 virtual bool operator == (const SemanticContext &other) const override;
118 virtual std::string toString() const override;
121 class ANTLR4CPP_PUBLIC SemanticContext::PrecedencePredicate : public SemanticContext {
123 const int precedence;
126 PrecedencePredicate();
129 PrecedencePredicate(int precedence);
131 virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) override;
132 virtual Ref<SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) override;
133 virtual int compareTo(PrecedencePredicate *o);
134 virtual size_t hashCode() const override;
135 virtual bool operator == (const SemanticContext &other) const override;
136 virtual std::string toString() const override;
140 * This is the base class for semantic context "operators", which operate on
141 * a collection of semantic context "operands".
145 class ANTLR4CPP_PUBLIC SemanticContext::Operator : public SemanticContext {
147 virtual ~Operator() override;
150 * Gets the operands for the semantic context operator.
152 * @return a collection of {@link SemanticContext} operands for the
158 virtual std::vector<Ref<SemanticContext>> getOperands() const = 0;
162 * A semantic context which is true whenever none of the contained contexts
165 class ANTLR4CPP_PUBLIC SemanticContext::AND : public SemanticContext::Operator {
167 std::vector<Ref<SemanticContext>> opnds;
169 AND(Ref<SemanticContext> const& a, Ref<SemanticContext> const& b) ;
171 virtual std::vector<Ref<SemanticContext>> getOperands() const override;
172 virtual bool operator == (const SemanticContext &other) const override;
173 virtual size_t hashCode() const override;
176 * The evaluation of predicates by this context is short-circuiting, but
179 virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) override;
180 virtual Ref<SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) override;
181 virtual std::string toString() const override;
185 * A semantic context which is true whenever at least one of the contained
188 class ANTLR4CPP_PUBLIC SemanticContext::OR : public SemanticContext::Operator {
190 std::vector<Ref<SemanticContext>> opnds;
192 OR(Ref<SemanticContext> const& a, Ref<SemanticContext> const& b);
194 virtual std::vector<Ref<SemanticContext>> getOperands() const override;
195 virtual bool operator == (const SemanticContext &other) const override;
196 virtual size_t hashCode() const override;
199 * The evaluation of predicates by this context is short-circuiting, but
202 virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) override;
203 virtual Ref<SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) override;
204 virtual std::string toString() const override;
208 } // namespace antlr4
210 // Hash function for SemanticContext, used in the MurmurHash::update function
213 using antlr4::atn::SemanticContext;
215 template <> struct hash<SemanticContext>
217 size_t operator () (SemanticContext &x) const