• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1%{
2#include "jqp.h"
3#include "jbl.h"
4
5
6#define YY_CTX_LOCAL 1
7#define YY_CTX_MEMBERS \
8  JQP_AUX *aux;
9
10struct _yycontext;
11
12static void _jqp_finish(struct _yycontext *yy);
13static void _jqp_debug(struct _yycontext *yy, const char *text);
14static void *_jqp_malloc(struct _yycontext *yy, size_t size);
15static void *_jqp_realloc(struct _yycontext *yy, void *ptr, size_t size);
16static JQPUNIT *_jqp_unit(struct _yycontext *yy);
17
18static void _jqp_op_negate(struct _yycontext *yy);
19static void _jqp_op_negate_reset(struct _yycontext *yy);
20
21static JQPUNIT *_jqp_string(struct _yycontext *yy, jqp_string_flavours_t flv, const char *text);
22static JQPUNIT *_jqp_unescaped_string(struct _yycontext *yy, jqp_string_flavours_t flv, const char *text);
23static JQPUNIT *_jqp_number(struct _yycontext *yy, jqp_int_flavours_t flv, const char *text);
24static JQPUNIT *_jqp_placeholder(struct _yycontext *yy, const char *text);
25static JQPUNIT *_jqp_unit_op(struct _yycontext *yy, const char *text);
26static JQPUNIT *_jqp_unit_join(struct _yycontext *yy, const char *text);
27static JQPUNIT *_jqp_expr(struct _yycontext *yy, JQPUNIT *left, JQPUNIT *op, JQPUNIT *right);
28static JQPUNIT *_jqp_node(struct _yycontext *yy, JQPUNIT *value);
29static JQPUNIT *_jqp_projection(struct _yycontext *yy, JQPUNIT *value, uint8_t flags);
30static void _jqp_set_skip(struct _yycontext *yy, JQPUNIT *unit);
31static void _jqp_set_limit(struct _yycontext *yy, JQPUNIT *unit);
32static void _jqp_add_orderby(struct _yycontext *yy, JQPUNIT *unit);
33static void _jqp_set_aggregate_count(struct _yycontext *yy);
34static void _jqp_set_noidx(struct _yycontext *yy);
35static void _jqp_set_inverse(struct _yycontext *yy);
36
37static JQPUNIT *_jqp_json_string(struct _yycontext *yy, const char *text);
38static JQPUNIT *_jqp_json_number(struct _yycontext *yy, const char *text);
39static JQPUNIT *_jqp_json_true_false_null(struct _yycontext *yy, const char *text);
40static JQPUNIT *_jqp_json_pair(struct _yycontext *yy, JQPUNIT *key, JQPUNIT *val);
41static JQPUNIT *_jqp_json_collect(struct _yycontext *yy, jbl_type_t type, JQPUNIT *until);
42
43static JQP_STACK *_jqp_push(struct _yycontext *yy);
44static void _jqp_unit_push(struct _yycontext *yy, JQPUNIT *unit);
45static JQPUNIT *_jqp_unit_pop(struct _yycontext *yy);
46static void _jqp_string_push(struct _yycontext *yy, char *str, bool dup);
47static char *_jqp_string_pop(struct _yycontext *yy);
48
49static JQPUNIT *_jqp_pop_filter_factor_chain(struct _yycontext *yy, JQPUNIT *until);
50static JQPUNIT *_jqp_pop_expr_chain(struct _yycontext *yy, JQPUNIT *until);
51static JQPUNIT *_jqp_pop_node_chain(struct _yycontext *yy, JQPUNIT *until);
52static JQPUNIT *_jqp_pop_projfields_chain(struct _yycontext *yy, JQPUNIT *until);
53static JQPUNIT *_jqp_pop_projection_nodes(struct _yycontext *yy, JQPUNIT *until);
54static JQPUNIT *_jqp_pop_ordernodes(struct _yycontext *yy, JQPUNIT *until);
55static JQPUNIT *_jqp_push_joined_projection(struct _yycontext *yy, JQPUNIT *p);
56static JQPUNIT *_jqp_pop_joined_projections(struct _yycontext *yy, JQPUNIT *until);
57
58static void _jqp_set_filters_expr(struct _yycontext *yy, JQPUNIT *expr);
59static JQPUNIT *_jqp_create_filterexpr_pk(struct _yycontext *yy, JQPUNIT *argument);
60static void _jqp_set_apply(struct _yycontext *yy, JQPUNIT *unit);
61static void _jqp_set_apply_delete(struct _yycontext *yy);
62static void _jqp_set_apply_upsert(struct _yycontext *yy, JQPUNIT *unit);
63static void _jqp_set_projection(struct _yycontext *yy, JQPUNIT *unit);
64
65#define YYSTYPE JQPUNIT*
66#define YY_MALLOC(yy_, sz_) _jqp_malloc(yy_, sz_)
67#define YY_REALLOC(yy_, ptr_, sz_) _jqp_realloc(yy_, ptr_, sz_)
68
69#define YY_INPUT(yy_, buf_, result_, max_size_)	        \
70  {	                                                    \
71    JQP_AUX *aux = (yy_)->aux;                           \
72    if (aux->rc || *(aux->buf + aux->pos) == '\0') {    \
73      result_ = 0;                                      \
74    } else {                                            \
75      char ch = *(aux->buf + aux->pos++);               \
76      result_ = 1;                                      \
77      *(buf_)= ch;                                      \
78    }                                                   \
79  }
80%}
81
82QUERY = s:QEXPR { _jqp_set_filters_expr(yy, s); }
83        (_ '|' _ (a:APPLY { _jqp_set_apply(yy, a); } | "del" { _jqp_set_apply_delete(yy); } | u:UPSERT { _jqp_set_apply_upsert(yy, u); } ) )?
84        (_ p:PROJECTION { _jqp_set_projection(yy, p); } )?
85        (_ OPTS )?
86        _ EOF { _jqp_finish(yy); }
87
88QEXPR = FILTEREXPR_PK | FILTEREXPR
89
90FILTEREXPR_PK = (a:FILTERANCHOR { _jqp_unit_push(yy, a); })?
91                '/' _ '=' _ ( p:PLACEHOLDER | p:NUMPK | p:NUMPK_ARR )
92                { $$ = _jqp_create_filterexpr_pk(yy, p) }
93
94FILTERJOIN = (<("and" | "or")> (__ "not" { _jqp_op_negate(yy); })?)   { $$ = _jqp_unit_join(yy, yytext); }
95
96APPLY      =  "apply" __ ( PLACEHOLDER | OBJJ | ARRJ )
97
98UPSERT =  "upsert" __ ( PLACEHOLDER | OBJJ | ARRJ )
99
100PROJECTION  = '|' _ (sn:PROJNODES { _jqp_unit_push(yy, sn); }
101                    (_ <PROJOIN> { _jqp_string_push(yy, yytext, true); } _ n:PROJNODES { _jqp_push_joined_projection(yy, n); } )*)
102                    { $$ = _jqp_pop_joined_projections(yy, sn); }
103
104OPTS        = '|' _ OPT (__ OPT)*
105
106OPT = SKIP | LIMIT | ORDERBY | COUNT | NOIDX | INVERSE
107
108SKIP = "skip" __ (<NUMI> { $$ = _jqp_number(yy, JQP_INT_SKIP, yytext); } | p:PLACEHOLDER { $$ = p; }) { _jqp_set_skip(yy, $$); }
109
110LIMIT = "limit" __ (<NUMI> { $$ = _jqp_number(yy, JQP_INT_LIMIT, yytext); } | p:PLACEHOLDER { $$ = p; }) { _jqp_set_limit(yy, $$); }
111
112COUNT = "count" { _jqp_set_aggregate_count(yy); }
113
114NOIDX = "noidx" { _jqp_set_noidx(yy); }
115
116INVERSE = "inverse" { _jqp_set_inverse(yy); }
117
118ORDERBY = ("asc" | "desc" { _jqp_op_negate(yy); })
119          __ ( p:ORDERNODES | p:PLACEHOLDER )
120          { p->string.flavour |= (yy->aux->negate ? JQP_STR_NEGATE : 0); _jqp_op_negate_reset(yy); _jqp_add_orderby(yy, p); }
121
122ORDERNODES = sn:ORDERNODE { _jqp_unit_push(yy, sn); } (n:ORDERNODE { _jqp_unit_push(yy, n); })* { $$ = _jqp_pop_ordernodes(yy, sn) }
123
124ORDERNODE = '/' PROJPROP
125
126PROJNODES = (a:PROJALL { $$ = _jqp_projection(yy, a, 0); }
127            | (sn:PROJNODE { _jqp_unit_push(yy, sn); } (n:PROJNODE { _jqp_unit_push(yy, n);})*) { $$ = _jqp_pop_projection_nodes(yy, sn); })
128
129PROJALL = "all" { $$ = _jqp_string(yy, JQP_STR_PROJALIAS, "all"); }
130
131PROJNODE = '/' (PROJFIELDS | PROJPROP)
132
133PROJFIELDS = ('{' _ sp:PROJPROP { _jqp_unit_push(yy, sp); } (_ ',' _ p:PROJPROP { _jqp_unit_push(yy, p); } )* _ '}')
134             { $$ = _jqp_pop_projfields_chain(yy, sp); }
135
136PROJPROP = STRN | PSTRP
137
138PROJOIN = ('+' | '-')
139
140PSTRP = <PCHP+> { $$ = _jqp_string(yy, 0, yytext); }
141
142PCHP = '\\' '\\'
143      | '\\' [bfnrt]
144      | '\\' 'u' HEX HEX HEX HEX
145      | !["/{},\t\n\r ] .
146
147
148FILTERFACTOR = (FILTER | '(' FILTEREXPR ')')
149
150FILTEREXPR = ff:FILTERFACTOR { _jqp_unit_push(yy, ff); }
151                (__ j:FILTERJOIN { _jqp_unit_push(yy, j); } __ f:FILTERFACTOR { _jqp_unit_push(yy, f); })* { $$ = _jqp_pop_filter_factor_chain(yy, ff); }
152
153FILTER = ((a:FILTERANCHOR { _jqp_unit_push(yy, a); })? fn:NODE { _jqp_unit_push(yy, fn); } (n:NODE { _jqp_unit_push(yy, n); })*) { $$ = _jqp_pop_node_chain(yy, fn); }
154
155FILTERANCHOR = '@' <([a-zA-Z0-9_\-]+)> { $$ = _jqp_string(yy, JQP_STR_ANCHOR, yytext); }
156
157
158NODE = '/' (n:STRN | n:NEXPR | n:STRP) { $$ = _jqp_node(yy, n); }
159
160NEXPR = ('[' _ n:NEXPAIR { _jqp_unit_push(yy, n); }
161          ( __ j:NEXJOIN { _jqp_unit_push(yy, j); } __ np:NEXPAIR { _jqp_unit_push(yy, np); })* _ ']')
162          { $$ = _jqp_pop_expr_chain(yy, n); }
163
164NEXJOIN = (<("and" | "or")> (__ "not" { _jqp_op_negate(yy); })?)        { $$ = _jqp_unit_join(yy, yytext); }
165
166NEXPAIR = (l:NEXLEFT _ o:NEXOP _ r:NEXRIGHT)                            { $$ = _jqp_expr(yy, l, o, r); }
167
168NEXLEFT = (DBLSTAR | STRSTAR | STRN | NEXPRLEFT | STRP)
169
170NEXPRLEFT = ('[' _ l:STRSTAR _ o:NEXOP _ r:NEXRIGHT _ ']')              { $$ = _jqp_expr(yy, l, o, r); }
171
172NEXRIGHT = (PLACEHOLDER | VALJ | STRP)
173
174PLACEHOLDER = ':' <([a-zA-Z0-9]+ | '?')>                                { $$ = _jqp_placeholder(yy, yytext); }
175
176NEXOP = ("not" __ { _jqp_op_negate(yy); })? <("in" | "ni" | "re")>      { $$ = _jqp_unit_op(yy, yytext); }
177        | <(">=" | "gte")>                                              { $$ = _jqp_unit_op(yy, yytext); }
178        | <("<=" | "lte")>                                              { $$ = _jqp_unit_op(yy, yytext); }
179        | ('!' _  { _jqp_op_negate(yy); })? <('=' | "eq" | '~')>        { $$ = _jqp_unit_op(yy, yytext); }
180        | <('>' | "gt")>                                                { $$ = _jqp_unit_op(yy, yytext); }
181        | <('<' | "lt")>                                                { $$ = _jqp_unit_op(yy, yytext); }
182        | <('~')>                                                       { $$ = _jqp_unit_op(yy, yytext); }
183
184STRP = <CHP+> { $$ = _jqp_unescaped_string(yy, 0, yytext); }
185
186DBLSTAR = "**" { $$ = _jqp_unescaped_string(yy, JQP_STR_DBL_STAR, "**"); }
187
188STRSTAR = "*" { $$ = _jqp_unescaped_string(yy, JQP_STR_STAR, "*"); }
189
190STRN = '"' <CHJ+> '"' { $$ = _jqp_unescaped_string(yy, JQP_STR_QUOTED, yytext); }
191
192OBJJ =  (s:SOBJJ { _jqp_unit_push(yy, s); }
193        _ (fp:PAIRJ { _jqp_unit_push(yy, fp); } (_ ',' _ p:PAIRJ { _jqp_unit_push(yy, p); })* )? _ '}')
194        { $$ = _jqp_json_collect(yy, JBV_OBJECT, s); }
195
196ARRJ =  (s:SARRJ { _jqp_unit_push(yy, s); }
197        _ (fv:VALJ { _jqp_unit_push(yy, fv); } (_ ',' _ v:VALJ { _jqp_unit_push(yy, v); })* )? _ ']')
198        { $$ = _jqp_json_collect(yy, JBV_ARRAY, s); }
199
200SOBJJ = '{' { $$ =  _jqp_unit(yy); }
201
202SARRJ = '[' { $$ =  _jqp_unit(yy); }
203
204PAIRJ = (s:STRJ _ ':' _ v:VALJ) { $$ = _jqp_json_pair(yy, s, v); }
205
206VALJ =    STRJ
207        | NUMJ
208        | OBJJ
209        | ARRJ
210        | "true"  { $$ = _jqp_json_true_false_null(yy, "true"); }
211        | "false" { $$ = _jqp_json_true_false_null(yy, "false"); }
212        | "null"  { $$ = _jqp_json_true_false_null(yy, "null"); }
213
214STRJ = '"' <(CHJ*)> '"' { $$ = _jqp_json_string(yy, yytext); }
215
216HEX = [0-9A-Fa-f]
217
218CHJ = '\\' '"'
219      | '\\' '\\'
220      | '\\' [bfnrt]
221      | '\\' 'u' HEX HEX HEX HEX
222      | !'"' .
223
224CHP = '\\' '\\'
225      | '\\' [bfnrt]
226      | '\\' 'u' HEX HEX HEX HEX
227      | ![/"[\]=><!\t\n\r() ] .
228
229NUMJ = <('-'? NUMI NUMF? NUME?)> { $$ = _jqp_json_number(yy, yytext); }
230
231NUMPK = <(NUMI)> { $$ = _jqp_json_number(yy, yytext); }
232
233NUMPK_ARR =  (s:SARRJ { _jqp_unit_push(yy, s); }
234            _ (fv:NUMPK { _jqp_unit_push(yy, fv); } (_ ',' _ v:NUMPK { _jqp_unit_push(yy, v); })* )? _ ']')
235            { $$ = _jqp_json_collect(yy, JBV_ARRAY, s); }
236
237NUMI = '0' | [1-9] [0-9]*
238
239NUMF = '.' [0-9]+
240
241NUME = [eE] [+-]? [0-9]+
242
243_ = SPACE*
244
245__ = SPACE+
246
247SPACE = ' ' | '\t' | EOL
248
249EOL = ('\r\n' | '\n' | '\r')
250
251EOF = !.
252
253%%
254
255#include "./inc/jqpx.c"