Document and tweak the generic visitor
Summary: Document and tweak the generic visitor Use the generic visitor for AST visiting Reviewers: buda, mislav.bradac, florijan Reviewed By: buda Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D128
This commit is contained in:
parent
6c7372b3c5
commit
74991c8289
@ -5,14 +5,14 @@
|
||||
|
||||
#include "database/graph_db.hpp"
|
||||
#include "query/frontend/ast/ast_visitor.hpp"
|
||||
#include "utils/visitor/visitable.hpp"
|
||||
|
||||
namespace query {
|
||||
|
||||
class Tree {
|
||||
public:
|
||||
class Tree : public ::utils::Visitable<TreeVisitorBase> {
|
||||
public:
|
||||
Tree(int uid) : uid_(uid) {}
|
||||
int uid() const { return uid_; }
|
||||
virtual void Accept(TreeVisitorBase &visitor) = 0;
|
||||
|
||||
private:
|
||||
const int uid_;
|
||||
@ -27,10 +27,7 @@ class Identifier : public Expression {
|
||||
public:
|
||||
Identifier(int uid, const std::string &name) : Expression(uid), name_(name) {}
|
||||
|
||||
void Accept(TreeVisitorBase &visitor) override {
|
||||
visitor.Visit(*this);
|
||||
visitor.PostVisit(*this);
|
||||
}
|
||||
DEFVISITABLE(TreeVisitorBase)
|
||||
|
||||
std::string name_;
|
||||
};
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/visitor/visitor.hpp"
|
||||
|
||||
namespace query {
|
||||
|
||||
// Forward declares for TreeVisitorBase
|
||||
@ -13,32 +15,8 @@ class Pattern;
|
||||
class NodeAtom;
|
||||
class EdgeAtom;
|
||||
|
||||
class TreeVisitorBase {
|
||||
public:
|
||||
virtual ~TreeVisitorBase() {}
|
||||
// Start of the tree is a Query.
|
||||
virtual void Visit(Query&) {}
|
||||
virtual void PostVisit(Query&) {}
|
||||
// Expressions
|
||||
virtual void Visit(NamedExpression&) {}
|
||||
virtual void PostVisit(NamedExpression&) {}
|
||||
virtual void Visit(Identifier&) {}
|
||||
virtual void PostVisit(Identifier&) {}
|
||||
virtual void PreVisit(PropertyLookup&) {}
|
||||
virtual void Visit(PropertyLookup&) {}
|
||||
virtual void PostVisit(PropertyLookup&) {}
|
||||
// Clauses
|
||||
virtual void Visit(Match&) {}
|
||||
virtual void PostVisit(Match&) {}
|
||||
virtual void Visit(Return&) {}
|
||||
virtual void PostVisit(Return&) {}
|
||||
// Pattern and its subparts.
|
||||
virtual void Visit(Pattern&) {}
|
||||
virtual void PostVisit(Pattern&) {}
|
||||
virtual void Visit(NodeAtom&) {}
|
||||
virtual void PostVisit(NodeAtom&) {}
|
||||
virtual void Visit(EdgeAtom&) {}
|
||||
virtual void PostVisit(EdgeAtom&) {}
|
||||
};
|
||||
using TreeVisitorBase =
|
||||
::utils::Visitor<Query, NamedExpression, Identifier, PropertyLookup, Match,
|
||||
Return, Pattern, NodeAtom, EdgeAtom>;
|
||||
|
||||
}
|
||||
|
@ -40,6 +40,9 @@ class ExpressionEvaluator : public TreeVisitorBase {
|
||||
return last;
|
||||
}
|
||||
|
||||
using TreeVisitorBase::Visit;
|
||||
using TreeVisitorBase::PostVisit;
|
||||
|
||||
void PostVisit(NamedExpression &named_expression) override {
|
||||
auto symbol = symbol_table_[named_expression];
|
||||
frame_[symbol.position_] = PopBack();
|
||||
|
@ -10,6 +10,9 @@ class SymbolGenerator : public TreeVisitorBase {
|
||||
public:
|
||||
SymbolGenerator(SymbolTable& symbol_table) : symbol_table_(symbol_table) {}
|
||||
|
||||
using TreeVisitorBase::Visit;
|
||||
using TreeVisitorBase::PostVisit;
|
||||
|
||||
// Clauses
|
||||
void PostVisit(Return& ret) override {
|
||||
for (auto &named_expr : ret.named_expressions_) {
|
||||
|
@ -1,7 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
template <class T>
|
||||
struct Visitable {
|
||||
namespace utils {
|
||||
|
||||
// Inherit from this class to allow visiting from TVisitor class.
|
||||
// Example usage:
|
||||
// class Expression : public Visitable<ExpressionVisitor> {
|
||||
// };
|
||||
// class Identifier : public ExpressionVisitor {
|
||||
// public:
|
||||
// DEFVISITABLE(ExpressionVisitor) // Use default Accept implementation
|
||||
// ....
|
||||
// };
|
||||
// class Literal : public Expression {
|
||||
// public:
|
||||
// void Accept(ExpressionVisitor &visitor) override {
|
||||
// // Implement custom Accept.
|
||||
// }
|
||||
// };
|
||||
template <class TVisitor>
|
||||
class Visitable {
|
||||
public:
|
||||
virtual ~Visitable() = default;
|
||||
virtual void accept(T& visitor) = 0;
|
||||
virtual void Accept(TVisitor&) = 0;
|
||||
|
||||
#define DEFVISITABLE(TVisitor) \
|
||||
void Accept(TVisitor &visitor) override \
|
||||
{ visitor.Visit(*this); visitor.PostVisit(*this); }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,37 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
namespace detail {
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
struct VisitorBase {
|
||||
class VisitorBase {
|
||||
public:
|
||||
virtual ~VisitorBase() = default;
|
||||
|
||||
virtual void visit(T&) {}
|
||||
virtual void post_visit(T&) {}
|
||||
virtual void Visit(T&) {}
|
||||
virtual void PostVisit(T&) {}
|
||||
};
|
||||
|
||||
template <typename... T>
|
||||
struct RecursiveVisitorBase;
|
||||
class RecursiveVisitorBase;
|
||||
|
||||
template <typename Head, typename... Tail>
|
||||
struct RecursiveVisitorBase<Head, Tail...> : VisitorBase<Head>,
|
||||
RecursiveVisitorBase<Tail...> {
|
||||
using VisitorBase<Head>::visit;
|
||||
using VisitorBase<Head>::post_visit;
|
||||
class RecursiveVisitorBase<Head, Tail...> : public VisitorBase<Head>,
|
||||
public RecursiveVisitorBase<Tail...> {
|
||||
public:
|
||||
using VisitorBase<Head>::Visit;
|
||||
using VisitorBase<Head>::PostVisit;
|
||||
|
||||
using RecursiveVisitorBase<Tail...>::visit;
|
||||
using RecursiveVisitorBase<Tail...>::post_visit;
|
||||
using RecursiveVisitorBase<Tail...>::Visit;
|
||||
using RecursiveVisitorBase<Tail...>::PostVisit;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct RecursiveVisitorBase<T> : public VisitorBase<T> {
|
||||
using VisitorBase<T>::visit;
|
||||
using VisitorBase<T>::post_visit;
|
||||
class RecursiveVisitorBase<T> : public VisitorBase<T> {
|
||||
public:
|
||||
using VisitorBase<T>::Visit;
|
||||
using VisitorBase<T>::PostVisit;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
struct Visitor : public detail::RecursiveVisitorBase<T...> {
|
||||
using detail::RecursiveVisitorBase<T...>::visit;
|
||||
using detail::RecursiveVisitorBase<T...>::post_visit;
|
||||
namespace utils {
|
||||
|
||||
// Inherit from this class if you want to visit TVisitable types.
|
||||
// Example usage:
|
||||
// // Typedef for convenience or to establish a base class of visitors.
|
||||
// typedef Visitor<Identifier, Literal> ExpressionVisitorBase;
|
||||
// class ExpressionVisitor : public ExpressionVisitorBase {
|
||||
// public:
|
||||
// using ExpressionVisitorBase::Visit;
|
||||
// using ExpressionVisitorBase::PostVisit;
|
||||
//
|
||||
// void Visit(Identifier &identifier) override {
|
||||
// // Custom implementation of visiting Identifier.
|
||||
// }
|
||||
// };
|
||||
template <typename... TVisitable>
|
||||
class Visitor : public RecursiveVisitorBase<TVisitable...> {
|
||||
public:
|
||||
using RecursiveVisitorBase<TVisitable...>::Visit;
|
||||
using RecursiveVisitorBase<TVisitable...>::PostVisit;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user