1 /****************************************************************************
3 ** Copyright (c) 2020 SoftAtHome
5 ** Redistribution and use in source and binary forms, with or
6 ** without modification, are permitted provided that the following
9 ** 1. Redistributions of source code must retain the above copyright
10 ** notice, this list of conditions and the following disclaimer.
12 ** 2. Redistributions in binary form must reproduce the above
13 ** copyright notice, this list of conditions and the following
14 ** disclaimer in the documentation and/or other materials provided
15 ** with the distribution.
17 ** Subject to the terms and conditions of this license, each
18 ** copyright holder and contributor hereby grants to those receiving
19 ** rights under this license a perpetual, worldwide, non-exclusive,
20 ** no-charge, royalty-free, irrevocable (except for failure to
21 ** satisfy the conditions of this license) patent license to make,
22 ** have made, use, offer to sell, sell, import, and otherwise
23 ** transfer this software, where such license applies only to those
24 ** patent claims, already acquired or hereafter acquired, licensable
25 ** by such copyright holder or contributor that are necessarily
28 ** (a) their Contribution(s) (the licensed copyrights of copyright
29 ** holders and non-copyrightable additions of contributors, in
30 ** source or binary form) alone; or
32 ** (b) combination of their Contribution(s) with the work of
33 ** authorship to which such Contribution(s) was added by such
34 ** copyright holder or contributor, if, at the time the Contribution
35 ** is added, such addition causes such combination to be necessarily
36 ** infringed. The patent license shall not apply to any other
37 ** combinations which include the Contribution.
39 ** Except as expressly stated above, no rights or licenses from any
40 ** copyright holder or contributor is granted under this license,
41 ** whether expressly, by implication, estoppel or otherwise.
45 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
46 ** CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
47 ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
48 ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49 ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
50 ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
51 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
52 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
53 ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
54 ** AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
56 ** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
57 ** POSSIBILITY OF SUCH DAMAGE.
59 ****************************************************************************/
63 %define parse.error verbose
64 %parse-param {void *ctx}
65 %lex-param {void *ctx}
75 #include <sys/types.h>
77 #include <amxc/amxc.h>
79 #include "amxp_expr_priv.h"
80 #include "amxp_expr.tab.h"
87 amxp_expr_node_t* node;
92 amxp_expr_comp_t comp;
93 amxc_string_t *ptrstr;
96 %token <cptr> MULTILINECOMMENT
97 %token <node> EOF_TOKEN
101 %token <boolean> BOOL
102 %token <integer> DIGIT
104 %token <comp> COMPERATOR
106 %type <node> stream expr conditional_expr logical_or_expr logical_and_expr
107 %type <node> primary value list_values
109 %type <cptr> function_header
114 int yylex(YYSTYPE* lvalp, YYLTYPE* llocp, void * yyscanner);
115 void yyerror(YYLTYPE* locp, void* scanner, const char* err);
116 void yywarning(YYLTYPE* locp, void* scanner, const char* err);
117 amxp_expr_t *yyget_extra ( void * yyscanner );
119 void yyerror(YYLTYPE* locp, void* scanner, const char* err) {
120 amxp_expr_t *context = (amxp_expr_t *)yyget_extra(scanner);
121 amxp_expr_printf("ERROR (%s@%d) - %s\n",
124 amxc_string_get(&context->msg, 0));
125 amxc_string_clean(&context->msg);
128 void yywarning(YYLTYPE* locp, void* scanner, const char* err) {
129 amxp_expr_t *context = (amxp_expr_t *)yyget_extra(scanner);
130 amxp_expr_printf("WARNING (%s@%d) - %s\n",
133 amxc_string_get(&context->msg, 0));
134 amxc_string_clean(&context->msg);
137 #define scanner x->scanner
138 #define parser_ctx ((amxp_expr_t *)yyget_extra(ctx))
151 | EOF_TOKEN { $$ = NULL; }
155 amxp_expr_node_t* node = NULL;
156 amxc_var_t* value = NULL;
157 amxp_expr_node_new(&node, amxp_expr_value);
158 amxc_var_new(&value);
159 amxc_var_set(bool, value, true);
160 amxp_expr_node_set_value(node, value);
161 amxp_expr_node_push(&parser_ctx->nodes, node);
173 | logical_or_expr LOR logical_and_expr {
174 amxp_expr_node_t* node = NULL;
175 amxp_expr_node_new(&node, amxp_expr_or);
176 amxp_expr_node_set_left(node, $1);
177 amxp_expr_node_set_right(node, $3);
178 amxp_expr_node_push(&parser_ctx->nodes, node);
185 | logical_and_expr LAND primary {
186 amxp_expr_node_t* node = NULL;
187 amxp_expr_node_new(&node, amxp_expr_and);
188 amxp_expr_node_set_left(node, $1);
189 amxp_expr_node_set_right(node, $3);
190 amxp_expr_node_push(&parser_ctx->nodes, node);
200 amxp_expr_node_t* node = NULL;
201 amxp_expr_node_new(&node, amxp_expr_not);
202 amxp_expr_node_set_left(node, $2);
203 amxp_expr_node_push(&parser_ctx->nodes, node);
208 amxp_expr_node_t* node = NULL;
209 amxp_expr_node_new(&node, amxp_expr_and);
210 amxp_expr_node_set_left(node, $1);
211 amxp_expr_node_set_right(node, $2);
212 amxp_expr_node_push(&parser_ctx->nodes, node);
215 | value COMPERATOR value {
216 amxp_expr_node_t* node = NULL;
217 amxp_expr_node_new(&node, amxp_expr_compare_oper);
218 amxp_expr_node_set_compop(node, $2);
219 amxp_expr_node_set_left(node, $1);
220 amxp_expr_node_set_right(node, $3);
221 amxp_expr_node_push(&parser_ctx->nodes, node);
224 | function_header '(' list_values ')' {
225 amxp_expr_node_t* node = NULL;
226 amxp_expr_node_new(&node, amxp_expr_bool_func);
227 amxp_expr_node_set_function(node, strdup($1.txt));
228 amxc_llist_for_each(it, &$3->right.args) {
229 amxp_expr_node_t* arg = amxc_container_of(it, amxp_expr_node_t, it);
230 amxp_expr_node_add_value(node, arg);
232 amxp_expr_node_delete(&$3);
233 amxp_expr_node_push(&parser_ctx->nodes, node);
240 amxc_var_t* value = NULL;
241 amxp_expr_node_t* node = NULL;
244 $1.txt[$1.length] = 0;
245 amxc_string_init(&txt, 0);
246 amxc_string_push_buffer(&txt, $1.txt, $1.length + 1);
247 amxc_string_trim(&txt, NULL);
248 amxc_var_new(&value);
249 amxp_expr_node_new(&node, amxp_expr_value);
250 amxc_var_set(cstring_t, value, amxc_string_take_buffer(&txt));
251 amxp_expr_node_set_value(node, value);
252 amxp_expr_node_push(&parser_ctx->nodes, node);
256 amxc_var_t* value = NULL;
257 amxp_expr_node_t* node = NULL;
258 amxc_var_new(&value);
259 amxp_expr_node_new(&node, amxp_expr_value);
260 amxc_var_set(int64_t, value, $1);
261 amxp_expr_node_set_value(node, value);
262 amxp_expr_node_push(&parser_ctx->nodes, node);
266 amxc_var_t* value = NULL;
267 amxp_expr_node_t* node = NULL;
268 amxc_var_new(&value);
269 amxp_expr_node_new(&node, amxp_expr_value);
270 amxc_var_set(bool, value, $1);
271 amxp_expr_node_set_value(node, value);
272 amxp_expr_node_push(&parser_ctx->nodes, node);
276 amxp_expr_node_t* node = NULL;
277 amxp_expr_node_new(&node, amxp_expr_field);
278 amxp_expr_node_set_field(node, amxc_string_take_buffer($1));
280 amxp_expr_node_push(&parser_ctx->nodes, node);
281 amxc_string_delete(&$1);
283 | '[' list_values ']' {
284 amxp_expr_node_get_value(parser_ctx, $2);
287 | function_header '(' list_values ')' {
288 amxp_expr_node_t* node = NULL;
289 amxp_expr_node_new(&node, amxp_expr_value_func);
290 amxp_expr_node_set_function(node, strdup($1.txt));
291 amxc_llist_for_each(it, &$3->right.args) {
292 amxp_expr_node_t* arg = amxc_container_of(it, amxp_expr_node_t, it);
293 amxp_expr_node_add_value(node, arg);
295 amxp_expr_node_delete(&$3);
296 amxp_expr_node_push(&parser_ctx->nodes, node);
303 $1.txt[$1.length] = 0;
310 amxp_expr_node_t* node = NULL;
311 amxp_expr_node_new(&node, amxp_expr_value);
312 amxp_expr_node_push(&parser_ctx->nodes, node);
315 | list_values ',' value {
316 amxp_expr_node_add_value($1, $3);
320 amxp_expr_node_t* node = NULL;
321 amxp_expr_node_new(&node, amxp_expr_value);
322 amxp_expr_node_add_value(node, $1);
323 amxp_expr_node_push(&parser_ctx->nodes, node);
330 $3.txt[$3.length] = 0;
331 amxc_string_appendf($1, ".%s", $3.txt);
334 amxc_string_appendf($1, ".%" PRId64, $3);
337 amxc_string_new(&$$,0);
338 $1.txt[$1.length] = 0;
339 amxc_string_appendf($$, "%s", $1.txt);
342 amxc_string_new(&$$,0);
343 $2.txt[$2.length] = 0;
344 amxc_string_appendf($$, ".%s", $2.txt);
347 amxc_string_new(&$$,0);
348 amxc_string_appendf($$, ".%" PRId64, $2);
351 amxc_string_new(&$$,0);
352 $1.txt[$1.length] = 0;
353 amxc_string_appendf($$, "%s", $1.txt);