GCC Code Coverage Report


Directory: src/
File: src/frontend/gyoji-frontend/syntax-node.hpp
Date: 2025-10-15 09:43:47
Exec Total Coverage
Lines: 5 5 100.0%
Functions: 2 2 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 #ifndef _GYOJI_INTERNAL
2 #error "This header is intended to be used internally as a part of the Gyoji front-end. Please include frontend.hpp instead."
3 #endif
4 #pragma once
5
6 /*!
7 * \addtogroup Frontend
8 * @{
9 */
10
11 /**
12 * @brief Abstract syntax tree
13 *
14 * @details
15 * Weakly-typed representation of the parse tree
16 * resulting from reading and parsing an input file.
17 * While the interface to the data is weakly typed,
18 * the underlying data can be accessed through
19 * a variant that exposes all of the different
20 * types of production that the grammar can produce.
21 */
22 namespace Gyoji::frontend::ast {
23
24 /**
25 * @brief Weakly-typed syntax node
26 *
27 * @details
28 * The syntax tree can be viewed as a tree of nodes
29 * that follow the structure of the parsed grammar.
30 *
31 * This view of the syntax tree can be processed
32 * in a weakly-typed sense where each node of
33 * type SyntaxNode may have zero or more children
34 * that represent grammar productions below them.
35 *
36 * Each of these nodes can also, optionally, be
37 * examined to find the specific strongly-typed
38 * tree node corresponding to the data parsed.
39 *
40 * For example, the top-level SyntaxNode will hold
41 * a TranslationUnit so that it can be extracted:
42 *
43 * <pre>
44 * SyntaxNode *s;
45 * if (s->holds_alternative<TranslationUnit>()) {
46 * const TranslationUnit & tu = s->get<TranslationUnit>();
47 * }
48 * </pre>
49 *
50 * The leaf nodes of the SyntaxTree will always be of
51 * type "Terminal" indicating that it is a "terminal"
52 * symbol of the grammer which corresponds to a parsed
53 * token from the lexer (gyoji.l).
54 */
55 class SyntaxNode {
56 public:
57 typedef std::variant<GYOJI_SYNTAX_NODE_VARIANT_LIST> specific_type_t;
58
59 /**
60 * Create a new syntax node of the given type holding
61 * the data associated with that production in the BNF
62 * grammar.
63 * @param _type Type of node this represents.
64 * @param _data The specific data associated with this node.
65 */
66 SyntaxNode(Gyoji::context::TokenID _type, specific_type_t _data, const Gyoji::context::SourceReference & _source_ref);
67 ~SyntaxNode();
68
69
70 /**
71 * This method returns a reference to an immutable array
72 * of children of this node.
73 */
74 const std::vector<std::reference_wrapper<const SyntaxNode>> & get_children() const;
75
76 /**
77 * This method returns an immutable reference to
78 * the type of the node.
79 */
80 const Gyoji::context::TokenID & get_type() const;
81
82 /**
83 * This interrogates the node to determine if it
84 * contains data of the specified type T.
85 * @tparam T Check type T to see if it is held in this node.
86 * @return True if this class contains that specific type of data.
87 */
88 46784 template <class T> bool has_data() const {
89 46784 return std::holds_alternative<T*>(data);
90 }
91
92 /**
93 * This returns an immutable reference to the
94 * data of type T contained in this node.
95 * Note that this is only safe to use if the
96 * holds_alternative<T>() returns true for
97 * this specific type.
98 * @tparam T The type of data to return.
99 */
100 16496 template <class T> const T &get_data() const {
101 16496 const T *d = std::get<T*>(data);
102 16496 return *d;
103 }
104
105 /**
106 * This method is provided so that callers
107 * of derived classes can be sure to get access
108 * to the SyntaxNode base-class instance.
109 */
110 const SyntaxNode & get_syntax_node() const;
111
112 /**
113 * Returns the source reference for where
114 * this node appears in the source tree.
115 */
116 const Gyoji::context::SourceReference & get_source_ref() const;
117
118 private:
119 // This list does NOT own its children, so
120 // the class deriving from this one must
121 // agree to own the pointers separately.
122 std::vector<std::reference_wrapper<const SyntaxNode>> children;
123 const Gyoji::context::SourceReference & source_ref;
124
125 protected:
126 // Children are owned by their parents, so this is
127 // private and can only be called by the
128 // deriving class.
129 void add_child(const SyntaxNode & node);
130 void prepend_child(const SyntaxNode & node);
131
132 Gyoji::context::TokenID type;
133 specific_type_t data;
134
135 };
136
137 };
138 /*! @} End of Doxygen Groups*/
139