GCC Code Coverage Report


Directory: src/
File: src/frontend/gyoji-frontend/syntax-node.hpp
Date: 2025-10-24 11:14:59
Exec Total Coverage
Lines: 5 5 100.0%
Functions: 2 2 100.0%
Branches: 0 0 -%

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