api documentation
[protos/libecoli.git] / include / ecoli_parse.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2016, Olivier MATZ <zer0@droids-corp.org>
3  */
4
5 /**
6  * @defgroup parse Parse
7  * @{
8  *
9  * @brief Create parse tree from string input and grammar tree
10  *
11  * Node parse API.
12  *
13  * The parse operation is to check if an input (a string or vector of
14  * strings) matches the node tree. On success, the result is stored in a
15  * tree that describes which part of the input matches which node.
16  *
17  * @}
18  */
19
20 #ifndef ECOLI_PARSE_
21 #define ECOLI_PARSE_
22
23 #include <sys/queue.h>
24 #include <sys/types.h>
25 #include <limits.h>
26 #include <stdio.h>
27 #include <stdbool.h>
28
29 struct ec_node;
30 struct ec_parse;
31
32 /**
33  * Create an empty parse tree.
34  *
35  * @return
36  *   The empty parse tree.
37  */
38 struct ec_parse *ec_parse(const struct ec_node *node);
39
40 /**
41  *
42  *
43  *
44  */
45 void ec_parse_free(struct ec_parse *parse);
46
47 /**
48  *
49  *
50  *
51  */
52 void ec_parse_free_children(struct ec_parse *parse);
53
54 /**
55  *
56  *
57  *
58  */
59 struct ec_parse *ec_parse_dup(const struct ec_parse *parse);
60
61 /**
62  *
63  *
64  *
65  */
66 // _get_ XXX
67 const struct ec_strvec *ec_parse_strvec(const struct ec_parse *parse);
68
69 /* a NULL return value is an error, with errno set
70   ENOTSUP: no ->parse() operation
71 */
72 /**
73  *
74  *
75  *
76  */
77 struct ec_parse *ec_node_parse(const struct ec_node *node, const char *str);
78
79 /**
80  *
81  *
82  *
83  */
84 struct ec_parse *ec_node_parse_strvec(const struct ec_node *node,
85                                 const struct ec_strvec *strvec);
86
87 /**
88  *
89  *
90  *
91  */
92 #define EC_PARSE_NOMATCH INT_MAX
93
94 /* internal: used by nodes
95  *
96  * state is the current parse tree, which is built piece by piece while
97  *   parsing the node tree: ec_node_parse_child() creates a new child in
98  *   this state parse tree, and calls the parse() method for the child
99  *   node, with state pointing to this new child. If it does not match,
100  *   the child is removed in the state, else it is kept, with its
101  *   possible descendants.
102  *
103  * return:
104  * the number of matched strings in strvec on success
105  * EC_PARSE_NOMATCH (positive) if it does not match
106  * -1 on error, and errno is set
107  */
108 int ec_node_parse_child(const struct ec_node *node,
109                         struct ec_parse *state,
110                         const struct ec_strvec *strvec);
111
112 /**
113  *
114  *
115  *
116  */
117 void ec_parse_link_child(struct ec_parse *parse,
118                         struct ec_parse *child);
119 /**
120  *
121  *
122  *
123  */
124 void ec_parse_unlink_child(struct ec_parse *parse,
125                         struct ec_parse *child);
126
127 /* keep the const */
128 #define ec_parse_get_root(parse) ({                             \
129         const struct ec_parse *p_ = parse; /* check type */     \
130         struct ec_parse *parse_ = (struct ec_parse *)parse;     \
131         typeof(parse) res_;                                     \
132         (void)p_;                                               \
133         res_ = __ec_parse_get_root(parse_);                     \
134         res_;                                                   \
135 })
136
137 /**
138  *
139  *
140  *
141  */
142 struct ec_parse *__ec_parse_get_root(struct ec_parse *parse);
143
144 /**
145  *
146  *
147  *
148  */
149 struct ec_parse *ec_parse_get_parent(const struct ec_parse *parse);
150
151 /**
152  * Get the first child of a tree.
153  *
154  */
155 struct ec_parse *ec_parse_get_first_child(const struct ec_parse *parse);
156
157 /**
158  *
159  *
160  *
161  */
162 struct ec_parse *ec_parse_get_last_child(const struct ec_parse *parse);
163
164 /**
165  *
166  *
167  *
168  */
169 struct ec_parse *ec_parse_next(const struct ec_parse *parse);
170
171 /**
172  *
173  *
174  *
175  */
176 #define EC_PARSE_FOREACH_CHILD(child, parse)                    \
177         for (child = ec_parse_get_first_child(parse);           \
178              child != NULL;                                     \
179              child = ec_parse_next(child))                      \
180
181 /**
182  *
183  *
184  *
185  */
186 bool ec_parse_has_child(const struct ec_parse *parse);
187
188 /**
189  *
190  *
191  *
192  */
193 const struct ec_node *ec_parse_get_node(const struct ec_parse *parse);
194
195 /**
196  *
197  *
198  *
199  */
200 void ec_parse_del_last_child(struct ec_parse *parse);
201
202 /**
203  *
204  *
205  *
206  */
207 struct ec_dict *ec_parse_get_attrs(struct ec_parse *parse);
208
209 /**
210  *
211  *
212  *
213  */
214 void ec_parse_dump(FILE *out, const struct ec_parse *parse);
215
216 /**
217  *
218  *
219  *
220  */
221 struct ec_parse *ec_parse_find(struct ec_parse *parse,
222         const char *id);
223
224 /**
225  *
226  *
227  *
228  */
229 struct ec_parse *ec_parse_find_next(struct ec_parse *root,
230                                 struct ec_parse *start,
231                                 const char *id, bool iter_children);
232
233 /**
234  * Iterate among parse tree
235  *
236  * Use it with:
237  * for (iter = state; iter != NULL; iter = EC_PARSE_ITER_NEXT(state, iter, 1))
238  */
239 struct ec_parse *__ec_parse_iter_next(const struct ec_parse *root,
240                                 struct ec_parse *parse, bool iter_children);
241
242 /* keep the const if any */
243 #define EC_PARSE_ITER_NEXT(root, parse, iter_children) ({               \
244         const struct ec_parse *p_ = parse; /* check type */             \
245         struct ec_parse *parse_ = (struct ec_parse *)parse;             \
246         typeof(parse) res_;                                             \
247         (void)p_;                                                       \
248         res_ = __ec_parse_iter_next(root, parse_, iter_children);       \
249         res_;                                                           \
250 })
251
252 /**
253  *
254  *
255  *
256  */
257 size_t ec_parse_len(const struct ec_parse *parse);
258
259 /**
260  *
261  *
262  *
263  */
264 size_t ec_parse_matches(const struct ec_parse *parse);
265
266 #endif