28 #ifndef PEGMATITE_AST_HPP 29 #define PEGMATITE_AST_HPP 34 #include <unordered_map> 47 std::string demangle(std::string);
49 #ifdef DEBUG_AST_CONSTRUCTION 50 template <
class T>
void debug_log(
const char *msg,
size_t depth, T *obj)
52 std::string demangled = demangle(
typeid(*obj).name());
53 fprintf(stderr,
"[%ld] %s %s (%p) off the AST stack\n",
54 depth, msg, demangled.c_str(),
static_cast<const void*
>(obj));
57 template <
class T>
void debug_log(
const char *,
size_t , T *) {}
58 #endif // DEBUG_AST_CONSTRUCTION 61 template <
class T,
bool Optional>
class ASTPtr;
66 typedef std::pair<const InputRange, std::unique_ptr<ASTNode>> ASTStackEntry;
69 typedef std::vector<ASTStackEntry> ASTStack;
72 #define PEGMATITE_RTTI(thisclass, superclass) 79 #define PEGMATITE_RTTI(thisclass, superclass) \ 82 static char *classKind() \ 84 static char thisclass ## id; \ 85 return &thisclass ## id; \ 88 virtual bool isa(char *x) override \ 90 return (x == classKind()) || \ 91 (superclass::isa(x)); \ 137 template <
class T,
bool Optional>
friend class ASTPtr;
138 template <
class T>
friend class ASTList;
139 template <
class T>
friend class BindAST;
154 static char ASTNodeid;
173 template <
class T>
bool isa()
175 return isa(T::classKind());
188 return t ? (isa<T>() ? static_cast<T*>(
this) :
nullptr) :
nullptr;
192 template <
class T> T*
get_as()
194 return dynamic_cast<T*
>(
this);
234 typedef std::vector<ASTMember *> ASTMember_vector;
239 ASTMember_vector members;
284 std::stringstream stream;
285 for_each(r.
begin(), r.
end(), [&](
char c) {stream << c;});
295 template <
class T,
bool Optional = false>
class ASTPtr :
public ASTMember 314 const std::unique_ptr<T> &operator *()
const 322 const std::unique_ptr<T> &operator ->()
const 328 explicit operator bool()
const noexcept
330 return static_cast<bool>(ptr);
338 if (st.empty() && Optional)
342 assert(!st.empty() &&
"Stack must not be empty");
343 ASTStackEntry &e = st.back();
349 (childRange.
end() > r.
end()))
351 assert(Optional &&
"Required object not found");
355 ASTNode *node = e.second.get();
358 T *obj = node->
get_as<T>();
360 assert((obj || Optional) &&
"Required objects must exist!");
362 if (Optional && !obj)
366 debug_log(
"Popped", st.size()-1, obj);
370 st.back().second.release();
372 ptr->parent_node = container_node;
379 std::unique_ptr<T> ptr;
410 return child_objects;
413 size_t size() {
return child_objects.size(); }
414 bool empty()
const {
return child_objects.size() == 0; }
415 typename container::iterator begin() {
return child_objects.begin(); }
416 typename container::iterator end() {
return child_objects.end(); }
417 typename container::reverse_iterator rbegin() {
return child_objects.rbegin(); }
418 typename container::reverse_iterator rend() {
return child_objects.rend(); }
420 typename container::const_iterator begin()
const 422 return child_objects.begin();
424 typename container::const_iterator end()
const 426 return child_objects.end();
428 typename container::const_reverse_iterator rbegin()
const 430 return child_objects.rbegin();
432 typename container::const_reverse_iterator rend()
const 434 return child_objects.rend();
446 if (st.empty())
break;
448 ASTStackEntry &e = st.back();
454 (childRange.
end() > r.
end()))
460 ASTNode *node = e.second.get();
463 T *obj = node->
get_as<T>();
468 debug_log(
"Popped", st.size()-1, obj);
475 child_objects.push_front(std::unique_ptr<T>(obj));
485 container child_objects;
490 for (
auto child : src.child_objects)
492 T *obj =
new T(child.get());
493 child_objects.push_back(obj);
508 std::unique_ptr<ASTNode> parse(
Input &i,
const Rule &g,
const Rule &ws,
534 std::unordered_map<const Rule*, parse_proc> handlers;
539 void set_parse_proc(
const Rule &r, parse_proc p);
544 static void bind_parse_proc(
const Rule &r, parse_proc p);
552 virtual parse_proc get_parse_proc(
const Rule &)
const;
563 std::unique_ptr<T> &ast)
const 565 std::unique_ptr<ASTNode> node = pegmatite::parse(i, g, ws, err, *
this);
566 T *n = node->get_as<T>();
582 template <
class T>
class BindAST 593 ASTStack *st =
reinterpret_cast<ASTStack *
>(d);
595 debug_log(
"Constructing", st->size(), obj);
596 obj->construct(range, *st);
597 st->push_back(std::make_pair(range, std::unique_ptr<ASTNode>(obj)));
598 debug_log(
"Constructed", st->size()-1, obj);
608 #endif //PEGMATITE_AST_HPP
virtual void construct(const InputRange &r, ASTStack &st)=0
Interface for constructing the AST node.
virtual ~ASTNode()
Destructor does nothing, virtual for subclasses to use.
Parser delegate abstract class.
Definition: parser.hh:793
An ASTPtr is a wrapper around a pointer to an AST object.
Definition: ast.hh:61
Base class for children of ASTContainer.
Definition: ast.hh:249
T * get_as()
Returns a pointer to this object as a pointer to a child class, or nullptr if the cast would be unsaf...
Definition: ast.hh:185
bool isa()
Returns true if this object is an instance of T.
Definition: ast.hh:173
A parser delegate that is responsible for creating AST nodes from the input.
Definition: ast.hh:523
virtual void construct(const InputRange &r, ASTStack &st)
Pops objects of type T from the stack (st) until no more objects can be popped.
Definition: ast.hh:441
ASTContainer * container_node
The container that owns this object.
Definition: ast.hh:273
static char * classKind()
Returns the unique identifier for this class.
Definition: ast.hh:152
virtual char * kind()
Returns the kind of object class.
Definition: ast.hh:148
Rule class, which represents a rule in a grammar.
Definition: parser.hh:554
bool parse(Input &i, const Rule &g, const Rule &ws, ErrorReporter err, std::unique_ptr< T > &ast) const
Parse an input i, starting from rule g in the grammar for which this is a delegate.
Definition: ast.hh:561
type of ast member vector.
Definition: ast.hh:211
ASTPtr()
Constructs the object in the.
Definition: ast.hh:301
A list of objects.
Definition: ast.hh:62
BindAST(const Rule &r)
Bind the AST class described in the grammar to the rule specified.
Definition: ast.hh:588
The BindAST class is responsible for binding an action to a rule.
Definition: ast.hh:63
static void bind_parse_proc(const Rule &r, parse_proc p)
Registers a callback for a specific rule in the instance of this class currently under construction i...
ASTNode()
Constructs the AST node, with a null parent.
Definition: ast.hh:105
Base class for AST nodes.
Definition: ast.hh:99
virtual void construct(const InputRange &r, ASTStack &st)
Pops the next matching object from the AST stack st and claims it.
Definition: ast.hh:336
const container & objects() const
returns the container of objects.
Definition: ast.hh:408
ASTNode * parent() const
Returns the parent of this AST node, or nullptr if there isn't one (either if this is the root...
Definition: ast.hh:123
std::list< std::unique_ptr< T > > container
list type.
Definition: ast.hh:392
ASTList(const ASTList< T > &src)
duplicates the objects of the given list.
Definition: ast.hh:400
ASTList()
the default constructor.
Definition: ast.hh:395
virtual bool isa(char *x)
Root implementation of the RTTI-replacement for builds not wishing to use RTTI.
Definition: ast.hh:163
ASTContainer * container() const
Returns the container of which this object is a field.
Definition: ast.hh:262