libamxo  4.3.4
Object Definition Language (ODL) parsing
amxo_parser.l
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (c) 2020 SoftAtHome
4 **
5 ** Redistribution and use in source and binary forms, with or
6 ** without modification, are permitted provided that the following
7 ** conditions are met:
8 **
9 ** 1. Redistributions of source code must retain the above copyright
10 ** notice, this list of conditions and the following disclaimer.
11 **
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.
16 **
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
26 ** infringed by:
27 **
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
31 **
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.
38 **
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.
42 **
43 ** DISCLAIMER
44 **
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.
58 **
59 ****************************************************************************/
60 %option reentrant bison-bridge
61 %option never-interactive
62 %option nounput
63 %option noinput
64 %option noyywrap
65 %option bison-locations
66 
67 %{
68  #define GNU_SOURCE
69  #include "amxo_parser_priv.h"
70  #include "amxo_parser_hooks_priv.h"
71  #include "amxo_parser.tab.h"
72 
73  #if __SIZE_WIDTH__ == 64
74  #define ssize_t_abs(x) labs(x)
75  #else
76  #define ssize_t_abs(x) abs(x)
77  #endif
78 
79  #define YY_EXTRA_TYPE amxo_parser_t*
80  #define YY_INPUT(buf,result,max_size) { \
81  ssize_t read_result = 0; \
82  read_result = yyextra->reader(yyextra, buf, max_size); \
83  if (read_result == -1) { \
84  YY_FATAL_ERROR( "input in flex scanner failed" ); \
85  } \
86  result = read_result > 0? ssize_t_abs(read_result):0; \
87  }
88 
89  extern int yylex \
90  (YYSTYPE * yylval_param , YYLTYPE* yylloc_param, yyscan_t yyscanner);
91 
92  #define UNUSED __attribute__((unused))
93  #define YY_DECL int yylex \
94  (YYSTYPE * yylval_param , UNUSED YYLTYPE* yylloc_param, yyscan_t yyscanner)
95 %}
96 
97 %option yylineno
98 
99 %{
100  #define YY_USER_ACTION { \
101  yylloc->first_line = yylineno; \
102  yyextra->line = yylineno; \
103  }
104 %}
105 
106 %x MULTI_LINE_COMMENT SINGLE_LINE_COMMENT LONG_TEXT LONG_TEXT_SQ FUNC_RESOLVER
107 
108 NEWLINE \r?\n
109 
110 %%
111 
112 "/*" { BEGIN( MULTI_LINE_COMMENT ); }
113 <MULTI_LINE_COMMENT>{
114  "*" { yymore(); }
115  [^*\n]+ { yymore(); }
116  [^*\n]*{NEWLINE} { yymore(); }
117  "*/" { yylval->cptr.txt = yytext;
118  yylval->cptr.length = yyleng - 2;
119  amxo_hooks_comment(yyextra, yylval->cptr.txt, yylval->cptr.length);
120  BEGIN(INITIAL);
121  }
122 }
123 
124 "#" { BEGIN( SINGLE_LINE_COMMENT ); }
125 "//" { BEGIN( SINGLE_LINE_COMMENT ); }
126 <SINGLE_LINE_COMMENT>{NEWLINE} { BEGIN(INITIAL); }
127 <SINGLE_LINE_COMMENT>"*" { }
128 <SINGLE_LINE_COMMENT>[^*\n]+ { yylval->cptr.txt = yytext;
129  yylval->cptr.length = yyleng;
130  amxo_hooks_comment(yyextra, yylval->cptr.txt, yylval->cptr.length);
131  }
132 
133 "'" { BEGIN(LONG_TEXT_SQ); }
134 <LONG_TEXT_SQ>{
135  "*" { yymore(); }
136  {NEWLINE} { yymore(); }
137  [^\\']+ { yymore(); }
138  [\\]. { yymore(); }
139  "'" { yylval->cptr.txt = yytext;
140  yylval->cptr.length = yyleng - 1;
141  BEGIN(INITIAL);
142  return TEXT;
143  }
144  . { yymore(); }
145 }
146 
147 
148 "\"" { BEGIN(LONG_TEXT); }
149 <LONG_TEXT>{
150  "*" { yymore(); }
151  {NEWLINE} { yymore(); }
152  [^\\"]+ { yymore(); }
153  [\\]. { yymore(); }
154  "\"" { yylval->cptr.txt = yytext;
155  yylval->cptr.length = yyleng - 1;
156  BEGIN(INITIAL);
157  return TEXT;
158  }
159  . { yymore(); }
160 }
161 
162 "<!" { BEGIN( FUNC_RESOLVER ); }
163 <FUNC_RESOLVER>{
164  {NEWLINE} { yymore(); }
165  "!>" { if (yyleng - 2 == 0) {
166  yylval->cptr.txt = NULL;
167  yylval->cptr.length = 0;
168  } else {
169  yylval->cptr.txt = yytext;
170  yylval->cptr.length = yyleng - 2;
171  }
172  BEGIN(INITIAL);
173  return RESOLVER;
174  }
175  . { yymore(); }
176 }
177 
178 [ \t] { }
179 [\n] { }
180 
181 <<EOF>> { yylval->integer = token_eof;
182  yyterminate();
183  return EOF_TOKEN;
184  }
185 
186 %config { yylval->integer = token_config;
187  amxo_hooks_start_section(yyextra, 0);
188  return CONFIG;
189  }
190 %define { yylval->integer = token_define;
191  amxo_hooks_start_section(yyextra, 1);
192  return DEFINE;
193  }
194 %populate { yylval->integer = token_populate;
195  amxo_hooks_start_section(yyextra, 2);
196  return POPULATE;
197  }
198 object { yylval->integer = token_object;
199  return OBJECT;
200  }
201 select { yylval->integer = token_object;
202  return SELECT;
203  }
204 mib { yylval->integer = token_mib;
205  return OBJECT;
206  }
207 parameter { yylval->integer = token_keyword;
208  return PARAMETER;
209  }
210 &include { yylval->integer = token_post_include;
211  return INCLUDE;
212  }
213 #include { yylval->integer = token_optional_include;
214  return INCLUDE;
215  }
216 \?include { yylval->integer = token_conditional_include;
217  return INCLUDE;
218  }
219 include { yylval->integer = token_include;
220  return INCLUDE;
221  }
222 requires { yylval->integer = token_requires;
223  return REQUIRES;
224  }
225 import { yylval->integer = token_import;
226  return IMPORT;
227  }
228 using { yylval->integer = token_import;
229  return USING;
230  }
231 as { yylval->integer = token_keyword;
232  return AS;
233  }
234 instance { yylval->integer = token_keyword;
235  return INSTANCE;
236  }
237 of { yylval->integer = token_keyword;
238  return OF;
239  }
240 add { yylval->integer = token_keyword;
241  return OF;
242  }
243 extend { yylval->integer = token_keyword;
244  return EXTEND;
245  }
246 
247 %read-only { yylval->integer = 1 << attr_readonly;
248  return SET_ATTRIBUTE;
249  }
250 %persistent { yylval->integer = 1 << attr_persistent;
251  return SET_ATTRIBUTE;
252  }
253 %private { yylval->integer = 1 << attr_private;
254  return SET_ATTRIBUTE;
255  }
256 %protected { yylval->integer = 1 << attr_protected;
257  return SET_ATTRIBUTE;
258  }
259 %template { yylval->integer = 1 << attr_template;
260  return SET_ATTRIBUTE;
261  }
262 %instance { yylval->integer = 1 << attr_instance;
263  return SET_ATTRIBUTE;
264  }
265 %volatile { yylval->integer = 1 << attr_variable;
266  return SET_ATTRIBUTE;
267  }
268 volatile { yylval->integer = 1 << attr_variable;
269  return SET_ATTRIBUTE;
270  }
271 %async { yylval->integer = 1 << attr_asynchronous;
272  return SET_ATTRIBUTE;
273  }
274 %in { yylval->integer = 1 << attr_in;
275  return SET_ATTRIBUTE;
276  }
277 %out { yylval->integer = 1 << attr_out;
278  return SET_ATTRIBUTE;
279  }
280 in { yylval->integer = 1 << attr_in;
281  return SET_ATTRIBUTE;
282  }
283 out { yylval->integer = 1 << attr_out;
284  return SET_ATTRIBUTE;
285  }
286 %mandatory { yylval->integer = 1 << attr_mandatory;
287  return SET_ATTRIBUTE;
288  }
289 %strict { yylval->integer = 1 << attr_strict;
290  return SET_ATTRIBUTE;
291  }
292 %key { yylval->integer = 1 << attr_key;
293  return SET_ATTRIBUTE;
294  }
295 %unique { yylval->integer = 1 << attr_unique;
296  return SET_ATTRIBUTE;
297  }
298 %mutable { yylval->integer = 1 << attr_mutable;
299  return SET_ATTRIBUTE;
300  }
301 %global { yylval->integer = token_keyword;
302  return GLOBAL;
303  }
304 !read-only { yylval->integer = 1 << attr_readonly;
305  return UNSET_ATTRIBUTE;
306  }
307 !persistent { yylval->integer = 1 << attr_persistent;
308  return UNSET_ATTRIBUTE;
309  }
310 !private { yylval->integer = 1 << attr_private;
311  return UNSET_ATTRIBUTE;
312  }
313 !protected { yylval->integer = 1 << attr_protected;
314  return UNSET_ATTRIBUTE;
315  }
316 !volatile { yylval->integer = 1 << attr_variable;
317  return UNSET_ATTRIBUTE;
318  }
319 void { yylval->integer = AMXC_VAR_ID_NULL;
320  return TYPE;
321  }
322 string { yylval->integer = AMXC_VAR_ID_CSTRING;
323  return TYPE;
324  }
325 csv_string { yylval->integer = AMXC_VAR_ID_CSV_STRING;
326  return TYPE;
327  }
328 ssv_string { yylval->integer = AMXC_VAR_ID_SSV_STRING;
329  return TYPE;
330  }
331 int8 { yylval->integer = AMXC_VAR_ID_INT8;
332  return TYPE;
333  }
334 int16 { yylval->integer = AMXC_VAR_ID_INT16;
335  return TYPE;
336  }
337 int32 { yylval->integer = AMXC_VAR_ID_INT32;
338  return TYPE;
339  }
340 int64 { yylval->integer = AMXC_VAR_ID_INT64;
341  return TYPE;
342  }
343 uint8 { yylval->integer = AMXC_VAR_ID_UINT8;
344  return TYPE;
345  }
346 uint16 { yylval->integer = AMXC_VAR_ID_UINT16;
347  return TYPE;
348  }
349 uint32 { yylval->integer = AMXC_VAR_ID_UINT32;
350  return TYPE;
351  }
352 uint64 { yylval->integer = AMXC_VAR_ID_UINT64;
353  return TYPE;
354  }
355 bool { yylval->integer = AMXC_VAR_ID_BOOL;
356  return TYPE;
357  }
358 list { yylval->integer = AMXC_VAR_ID_LIST;
359  return TYPE;
360  }
361 htable { yylval->integer = AMXC_VAR_ID_HTABLE;
362  return TYPE;
363  }
364 fd { yylval->integer = AMXC_VAR_ID_FD;
365  return TYPE;
366  }
367 variant { yylval->integer = AMXC_VAR_ID_ANY;
368  return TYPE;
369  }
370 double { yylval->integer = AMXC_VAR_ID_DOUBLE;
371  return TYPE;
372  }
373 datetime { yylval->integer = AMXC_VAR_ID_TIMESTAMP;
374  return TYPE;
375  }
376 
377 true { yylval->boolean = true;
378  return BOOL;
379  }
380 false { yylval->boolean = false;
381  return BOOL;
382  }
383 
384 RTLD_NOW { yylval->integer = RTLD_NOW;
385  return LDFLAG;
386  }
387 
388 RTLD_GLOBAL { yylval->integer = RTLD_GLOBAL;
389  return LDFLAG;
390  }
391 
392 RTLD_NODELETE { yylval->integer = RTLD_NODELETE;
393  return LDFLAG;
394  }
395 
396 entry-point { yylval->integer = token_keyword;
397  return ENTRY;
398  }
399 
400 with { yylval->integer = token_keyword;
401  return WITH;
402  }
403 counted { yylval->integer = token_keyword;
404  return COUNTER;
405  }
406 on { yylval->integer = token_keyword;
407  return ON;
408  }
409 default { yylval->integer = token_keyword;
410  return DEFAULT;
411  }
412 
413 action { yylval->integer = token_keyword;
414  return ACTION_KW;
415  }
416 event { yylval->integer = token_keyword;
417  return EVENT;
418  }
419 filter { yylval->integer = token_keyword;
420  return FILTER;
421  }
422 call { yylval->integer = token_keyword;
423  return CALL;
424  }
425 regexp { yylval->integer = token_keyword;
426  return REGEXP;
427  }
428 userflags { yylval->integer = token_keyword;
429  return FLAGS;
430  }
431 print { yylval->integer = token_keyword;
432  return PRINT;
433  }
434 synchronize { yylval->integer = token_keyword;
435  return SYNC;
436  }
437 %batch { yylval->integer = AMXS_SYNC_PARAM_BATCH;
438  return SYNC_ATTRIBUTE;
439  }
440 "->" { yylval->integer = AMXS_SYNC_ONLY_A_TO_B;
441  return DIRECTION;
442  }
443 "<-" { yylval->integer = AMXS_SYNC_ONLY_B_TO_A;
444  return DIRECTION;
445  }
446 "<->" { yylval->integer = AMXS_SYNC_DEFAULT;
447  return DIRECTION;
448  }
449 (-|\+){0,1}[[:digit:]]+ { char *endptr = NULL;
450  yylval->integer = strtoll(yytext, &endptr, 0);
451  return DIGIT;
452  }
453 (-|\+){0,1}0x[A-Fa-f0-9]+ { char *endptr = NULL;
454  yylval->integer = strtoll(yytext, &endptr, 16);
455  return DIGIT;
456  }
457 (-|\+){0,1}0b[0-1]+ { char *endptr = NULL;
458  yylval->integer = strtoll(yytext + 2, &endptr, 2);
459  return DIGIT;
460  }
461 [a-zA-Z0-9\-_]+ { yylval->cptr.txt = yytext;
462  yylval->cptr.length = yyleng;
463  return STRING;
464  }
465 
466 \n|. { return yytext[0]; }
467 
468 %%
469 
470 void amxo_parser_create_lex(amxo_parser_t *parser) {
471  yylex_init(&parser->scanner);
472  yyset_extra(parser, parser->scanner);
473 }
474 
475 void amxo_parser_destroy_lex(amxo_parser_t *parser) {
476  yylex_destroy(parser->scanner);
477 }