#pragma once
#include "Recognizer.h"
#include "support/CPPUtils.h"
#include "atn/SemanticContextType.h"
namespace antlr4 {
namespace atn {
class ANTLR4CPP_PUBLIC SemanticContext : public std::enable_shared_from_this<SemanticContext> {
public:
virtual ~SemanticContext() = default;
SemanticContextType getContextType() const { return _contextType; }
virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) const = 0;
virtual Ref<const SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) const;
virtual size_t hashCode() const = 0;
virtual bool equals(const SemanticContext &other) const = 0;
virtual std::string toString() const = 0;
static Ref<const SemanticContext> And(Ref<const SemanticContext> a, Ref<const SemanticContext> b);
static Ref<const SemanticContext> Or(Ref<const SemanticContext> a, Ref<const SemanticContext> b);
class Empty;
class Predicate;
class PrecedencePredicate;
class Operator;
class AND;
class OR;
protected:
explicit SemanticContext(SemanticContextType contextType) : _contextType(contextType) {}
private:
const SemanticContextType _contextType;
};
inline bool operator==(const SemanticContext &lhs, const SemanticContext &rhs) {
return lhs.equals(rhs);
}
inline bool operator!=(const SemanticContext &lhs, const SemanticContext &rhs) {
return !operator==(lhs, rhs);
}
class ANTLR4CPP_PUBLIC SemanticContext::Empty : public SemanticContext{
public:
static const Ref<const SemanticContext> Instance;
};
class ANTLR4CPP_PUBLIC SemanticContext::Predicate final : public SemanticContext {
public:
static bool is(const SemanticContext &semanticContext) { return semanticContext.getContextType() == SemanticContextType::PREDICATE; }
static bool is(const SemanticContext *semanticContext) { return semanticContext != nullptr && is(*semanticContext); }
const size_t ruleIndex;
const size_t predIndex;
const bool isCtxDependent;
Predicate(size_t ruleIndex, size_t predIndex, bool isCtxDependent);
bool eval(Recognizer *parser, RuleContext *parserCallStack) const override;
size_t hashCode() const override;
bool equals(const SemanticContext &other) const override;
std::string toString() const override;
};
class ANTLR4CPP_PUBLIC SemanticContext::PrecedencePredicate final : public SemanticContext {
public:
static bool is(const SemanticContext &semanticContext) { return semanticContext.getContextType() == SemanticContextType::PRECEDENCE; }
static bool is(const SemanticContext *semanticContext) { return semanticContext != nullptr && is(*semanticContext); }
const int precedence;
explicit PrecedencePredicate(int precedence);
bool eval(Recognizer *parser, RuleContext *parserCallStack) const override;
Ref<const SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) const override;
size_t hashCode() const override;
bool equals(const SemanticContext &other) const override;
std::string toString() const override;
};
class ANTLR4CPP_PUBLIC SemanticContext::Operator : public SemanticContext {
public:
static bool is(const SemanticContext &semanticContext) {
const auto contextType = semanticContext.getContextType();
return contextType == SemanticContextType::AND || contextType == SemanticContextType::OR;
}
static bool is(const SemanticContext *semanticContext) { return semanticContext != nullptr && is(*semanticContext); }
virtual const std::vector<Ref<const SemanticContext>>& getOperands() const = 0;
protected:
using SemanticContext::SemanticContext;
};
class ANTLR4CPP_PUBLIC SemanticContext::AND final : public SemanticContext::Operator {
public:
static bool is(const SemanticContext &semanticContext) { return semanticContext.getContextType() == SemanticContextType::AND; }
static bool is(const SemanticContext *semanticContext) { return semanticContext != nullptr && is(*semanticContext); }
AND(Ref<const SemanticContext> a, Ref<const SemanticContext> b) ;
const std::vector<Ref<const SemanticContext>>& getOperands() const override;
bool eval(Recognizer *parser, RuleContext *parserCallStack) const override;
Ref<const SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) const override;
size_t hashCode() const override;
bool equals(const SemanticContext &other) const override;
std::string toString() const override;
private:
std::vector<Ref<const SemanticContext>> _opnds;
};
class ANTLR4CPP_PUBLIC SemanticContext::OR final : public SemanticContext::Operator {
public:
static bool is(const SemanticContext &semanticContext) { return semanticContext.getContextType() == SemanticContextType::OR; }
static bool is(const SemanticContext *semanticContext) { return semanticContext != nullptr && is(*semanticContext); }
OR(Ref<const SemanticContext> a, Ref<const SemanticContext> b);
const std::vector<Ref<const SemanticContext>>& getOperands() const override;
bool eval(Recognizer *parser, RuleContext *parserCallStack) const override;
Ref<const SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) const override;
size_t hashCode() const override;
bool equals(const SemanticContext &other) const override;
std::string toString() const override;
private:
std::vector<Ref<const SemanticContext>> _opnds;
};
} }
namespace std {
template <>
struct hash<::antlr4::atn::SemanticContext> {
size_t operator()(const ::antlr4::atn::SemanticContext &semanticContext) const {
return semanticContext.hashCode();
}
};
}