| /* 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. |
| */ |
| |
| #pragma once |
| |
| #include "Recognizer.h" |
| #include "support/CPPUtils.h" |
| |
| namespace antlr4 { |
| namespace atn { |
| |
| /// A tree structure used to record the semantic context in which |
| /// an ATN configuration is valid. It's either a single predicate, |
| /// a conjunction "p1 && p2", or a sum of products "p1||p2". |
| /// |
| /// I have scoped the AND, OR, and Predicate subclasses of |
| /// SemanticContext within the scope of this outer class. |
| class ANTLR4CPP_PUBLIC SemanticContext : public std::enable_shared_from_this<SemanticContext> { |
| public: |
| struct Hasher |
| { |
| size_t operator()(Ref<SemanticContext> const& k) const { |
| return k->hashCode(); |
| } |
| }; |
| |
| struct Comparer { |
| bool operator()(Ref<SemanticContext> const& lhs, Ref<SemanticContext> const& rhs) const { |
| if (lhs == rhs) |
| return true; |
| return (lhs->hashCode() == rhs->hashCode()) && (*lhs == *rhs); |
| } |
| }; |
| |
| |
| using Set = std::unordered_set<Ref<SemanticContext>, Hasher, Comparer>; |
| |
| /** |
| * The default {@link SemanticContext}, which is semantically equivalent to |
| * a predicate of the form {@code {true}?}. |
| */ |
| static const Ref<SemanticContext> NONE; |
| |
| virtual ~SemanticContext(); |
| |
| virtual size_t hashCode() const = 0; |
| virtual std::string toString() const = 0; |
| virtual bool operator == (const SemanticContext &other) const = 0; |
| virtual bool operator != (const SemanticContext &other) const; |
| |
| /// <summary> |
| /// For context independent predicates, we evaluate them without a local |
| /// context (i.e., null context). That way, we can evaluate them without |
| /// having to create proper rule-specific context during prediction (as |
| /// opposed to the parser, which creates them naturally). In a practical |
| /// sense, this avoids a cast exception from RuleContext to myruleContext. |
| /// <p/> |
| /// For context dependent predicates, we must pass in a local context so that |
| /// references such as $arg evaluate properly as _localctx.arg. We only |
| /// capture context dependent predicates in the context in which we begin |
| /// prediction, so we passed in the outer context here in case of context |
| /// dependent predicate evaluation. |
| /// </summary> |
| virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) = 0; |
| |
| /** |
| * Evaluate the precedence predicates for the context and reduce the result. |
| * |
| * @param parser The parser instance. |
| * @param parserCallStack |
| * @return The simplified semantic context after precedence predicates are |
| * evaluated, which will be one of the following values. |
| * <ul> |
| * <li>{@link #NONE}: if the predicate simplifies to {@code true} after |
| * precedence predicates are evaluated.</li> |
| * <li>{@code null}: if the predicate simplifies to {@code false} after |
| * precedence predicates are evaluated.</li> |
| * <li>{@code this}: if the semantic context is not changed as a result of |
| * precedence predicate evaluation.</li> |
| * <li>A non-{@code null} {@link SemanticContext}: the new simplified |
| * semantic context after precedence predicates are evaluated.</li> |
| * </ul> |
| */ |
| virtual Ref<SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack); |
| |
| static Ref<SemanticContext> And(Ref<SemanticContext> const& a, Ref<SemanticContext> const& b); |
| |
| /// See also: ParserATNSimulator::getPredsForAmbigAlts. |
| static Ref<SemanticContext> Or(Ref<SemanticContext> const& a, Ref<SemanticContext> const& b); |
| |
| class Predicate; |
| class PrecedencePredicate; |
| class Operator; |
| class AND; |
| class OR; |
| |
| private: |
| static std::vector<Ref<PrecedencePredicate>> filterPrecedencePredicates(const Set &collection); |
| }; |
| |
| class ANTLR4CPP_PUBLIC SemanticContext::Predicate : public SemanticContext { |
| public: |
| const size_t ruleIndex; |
| const size_t predIndex; |
| const bool isCtxDependent; // e.g., $i ref in pred |
| |
| protected: |
| Predicate(); |
| |
| public: |
| Predicate(size_t ruleIndex, size_t predIndex, bool isCtxDependent); |
| |
| virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) override; |
| virtual size_t hashCode() const override; |
| virtual bool operator == (const SemanticContext &other) const override; |
| virtual std::string toString() const override; |
| }; |
| |
| class ANTLR4CPP_PUBLIC SemanticContext::PrecedencePredicate : public SemanticContext { |
| public: |
| const int precedence; |
| |
| protected: |
| PrecedencePredicate(); |
| |
| public: |
| PrecedencePredicate(int precedence); |
| |
| virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) override; |
| virtual Ref<SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) override; |
| virtual int compareTo(PrecedencePredicate *o); |
| virtual size_t hashCode() const override; |
| virtual bool operator == (const SemanticContext &other) const override; |
| virtual std::string toString() const override; |
| }; |
| |
| /** |
| * This is the base class for semantic context "operators", which operate on |
| * a collection of semantic context "operands". |
| * |
| * @since 4.3 |
| */ |
| class ANTLR4CPP_PUBLIC SemanticContext::Operator : public SemanticContext { |
| public: |
| virtual ~Operator() override; |
| |
| /** |
| * Gets the operands for the semantic context operator. |
| * |
| * @return a collection of {@link SemanticContext} operands for the |
| * operator. |
| * |
| * @since 4.3 |
| */ |
| |
| virtual std::vector<Ref<SemanticContext>> getOperands() const = 0; |
| }; |
| |
| /** |
| * A semantic context which is true whenever none of the contained contexts |
| * is false. |
| */ |
| class ANTLR4CPP_PUBLIC SemanticContext::AND : public SemanticContext::Operator { |
| public: |
| std::vector<Ref<SemanticContext>> opnds; |
| |
| AND(Ref<SemanticContext> const& a, Ref<SemanticContext> const& b) ; |
| |
| virtual std::vector<Ref<SemanticContext>> getOperands() const override; |
| virtual bool operator == (const SemanticContext &other) const override; |
| virtual size_t hashCode() const override; |
| |
| /** |
| * The evaluation of predicates by this context is short-circuiting, but |
| * unordered.</p> |
| */ |
| virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) override; |
| virtual Ref<SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) override; |
| virtual std::string toString() const override; |
| }; |
| |
| /** |
| * A semantic context which is true whenever at least one of the contained |
| * contexts is true. |
| */ |
| class ANTLR4CPP_PUBLIC SemanticContext::OR : public SemanticContext::Operator { |
| public: |
| std::vector<Ref<SemanticContext>> opnds; |
| |
| OR(Ref<SemanticContext> const& a, Ref<SemanticContext> const& b); |
| |
| virtual std::vector<Ref<SemanticContext>> getOperands() const override; |
| virtual bool operator == (const SemanticContext &other) const override; |
| virtual size_t hashCode() const override; |
| |
| /** |
| * The evaluation of predicates by this context is short-circuiting, but |
| * unordered. |
| */ |
| virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) override; |
| virtual Ref<SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) override; |
| virtual std::string toString() const override; |
| }; |
| |
| } // namespace atn |
| } // namespace antlr4 |
| |
| // Hash function for SemanticContext, used in the MurmurHash::update function |
| |
| namespace std { |
| using antlr4::atn::SemanticContext; |
| |
| template <> struct hash<SemanticContext> |
| { |
| size_t operator () (SemanticContext &x) const |
| { |
| return x.hashCode(); |
| } |
| }; |
| } |