Nearly CC
An educational compiler skeleton
node.h
1 // Copyright (c) 2021-2023, David H. Hovemeyer <david.hovemeyer@gmail.com>
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
17 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19 // OTHER DEALINGS IN THE SOFTWARE.
20 
21 #ifndef NODE_H
22 #define NODE_H
23 
24 #include <vector>
25 #include <string>
26 #include "location.h"
27 #include "node_base.h"
28 
29 // Tree node class, suitable for parse trees and ASTs.
30 // Nodes can also be used as tokens returned by a lexer.
31 // Note that parent nodes take responsibility for deleting
32 // their children, so to delete an entire tree, it is
33 // sufficient to delete the root.
34 
35 class Node : public NodeBase {
36 private:
37  int m_tag;
38  std::vector<Node *> m_kids;
39  std::string m_str;
40  Location m_loc;
41  bool m_loc_was_set_explicitly;
42 
43  // no value semantics
44  Node(const Node &);
45  Node &operator=(const Node &);
46 
47  Node(int tag, const std::string &str, const std::vector<Node *> &kids);
48  Node(int tag, const std::string &str, const std::initializer_list<Node *> kids);
49 
50 public:
51  typedef std::vector<Node *>::const_iterator const_iterator;
52 
53  Node(int tag);
54  Node(int tag, std::initializer_list<Node *> kids);
55  Node(int tag, const std::vector<Node *> &kids);
56  Node(int tag, const std::string &str);
57 
58  virtual ~Node();
59 
60  int get_tag() const { return m_tag; }
61  void set_tag(int tag) { m_tag = tag; }
62 
63  std::string get_str() const { return m_str; }
64  void set_str(const std::string &str) { m_str = str; }
65 
66  void append_kid(Node *kid);
67  void prepend_kid(Node *kid);
68  unsigned get_num_kids() const { return unsigned(m_kids.size()); }
69  Node *get_kid(unsigned index) const { return m_kids.at(index); }
70  Node *get_last_kid() const { return m_kids.back(); }
71  void shift_kid(); // removes the first child
72 
73  // this is useful for restructuring the tree,
74  // but should be used with care
75  void set_kid(unsigned index, Node *kid) { m_kids.at(index) = kid; }
76 
77  const_iterator cbegin() const { return m_kids.cbegin(); }
78  const_iterator cend() const { return m_kids.cend(); }
79 
80  void set_loc(const Location &loc) { m_loc = loc; m_loc_was_set_explicitly = true; }
81  const Location &get_loc() const { return m_loc; }
82 
83  // do a preorder traversal of the tree, invoking specified
84  // function on each node
85  template<typename Fn>
86  void preorder(Fn fn) {
87  fn(this);
88  for (auto i = m_kids.begin(); i != m_kids.end(); ++i) {
89  (*i)->preorder(fn);
90  }
91  }
92 
93  // invoke a function on each child
94  template<typename Fn>
95  void each_child(Fn fn) const {
96  for (auto i = m_kids.begin(); i != m_kids.end(); ++i) {
97  fn(*i);
98  }
99  }
100 };
101 
102 #endif // NODE_H
Definition: location.h:26
The Node class will inherit from this type, so you can use it to define any attributes and methods th...
Definition: node_base.h:43
Definition: node.h:35