fb7ccd8601a244872525d47349eebfb3a3c4de46
[m6w6/libmemcached] / libmemcached / options / parser.yy
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * Libmemcached Scanner and Parser
4 *
5 * Copyright (C) 2011 DataDifferental, http://datadifferential.com
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 %error-verbose
22 %debug
23 %defines
24 %expect 0
25 %output "libmemcached/options/parser.cc"
26 %defines "libmemcached/options/parser.h"
27 %lex-param { yyscan_t *scanner }
28 %name-prefix="libmemcached_"
29 %parse-param { Context *context }
30 %parse-param { yyscan_t *scanner }
31 %pure-parser
32 %require "2.2"
33 %start begin
34 %verbose
35
36 %{
37
38 #include <config.h>
39
40 #include <stdint.h>
41
42 #include <libmemcached/options/context.h>
43 #include <libmemcached/options/build.h>
44 #include <libmemcached/options/string.h>
45 #include <libmemcached/options/symbol.h>
46 #include <libmemcached/visibility.h>
47 #include <libmemcached/prefix_key.h>
48
49 #pragma GCC diagnostic ignored "-Wold-style-cast"
50 #include <libmemcached/options/scanner.h>
51
52 int libmemcached_lex(YYSTYPE* lvalp, void* scanner);
53
54 #define parser_abort(A, B) do { parser::abort_func((A), (B)); YYABORT; } while (0)
55
56 inline void libmemcached_error(Context *context, yyscan_t *scanner, const char *error)
57 {
58 if (not context->end())
59 parser::abort_func(context, error);
60 }
61
62 int libmemcached_parse(Context*, yyscan_t *);
63 void Context::start()
64 {
65 libmemcached_parse(this, scanner);
66 }
67
68 %}
69
70 %token COMMENT
71 %token END
72 %token ERROR
73 %token RESET
74 %token PARSER_DEBUG
75 %token INCLUDE
76 %token CONFIGURE_FILE
77 %token EMPTY_LINE
78 %token SERVER
79 %token SERVERS
80 %token SERVERS_OPTION
81 %token UNKNOWN_OPTION
82 %token UNKNOWN
83
84 /* All behavior options */
85 %token AUTO_EJECT_HOSTS
86 %token BINARY_PROTOCOL
87 %token BUFFER_REQUESTS
88 %token CACHE_LOOKUPS
89 %token CONNECT_TIMEOUT
90 %token _CORK
91 %token DISTRIBUTION
92 %token HASH
93 %token HASH_WITH_PREFIX_KEY
94 %token IO_BYTES_WATERMARK
95 %token IO_KEY_PREFETCH
96 %token IO_MSG_WATERMARK
97 %token KETAMA
98 %token KETAMA_HASH
99 %token KETAMA_WEIGHTED
100 %token NOREPLY
101 %token NUMBER_OF_REPLICAS
102 %token POLL_TIMEOUT
103 %token RANDOMIZE_REPLICA_READ
104 %token RCV_TIMEOUT
105 %token RETRY_TIMEOUT
106 %token SERVER_FAILURE_LIMIT
107 %token SND_TIMEOUT
108 %token SOCKET_RECV_SIZE
109 %token SOCKET_SEND_SIZE
110 %token SORT_HOSTS
111 %token SUPPORT_CAS
112 %token _TCP_NODELAY
113 %token _TCP_KEEPALIVE
114 %token _TCP_KEEPIDLE
115 %token USER_DATA
116 %token USE_UDP
117 %token VERIFY_KEY
118
119 /* Callbacks */
120 %token PREFIX_KEY
121
122 /* Hash types */
123 %token MD5
124 %token CRC
125 %token FNV1_64
126 %token FNV1A_64
127 %token FNV1_32
128 %token FNV1A_32
129 %token HSIEH
130 %token MURMUR
131 %token JENKINS
132
133 /* Distributions */
134 %token CONSISTENT
135 %token MODULA
136 %token RANDOM
137
138 /* Boolean values */
139 %token <boolean> TRUE
140 %token <boolean> FALSE
141
142 %nonassoc ','
143 %nonassoc '='
144
145 %token <number> NUMBER
146 %token <number> FLOAT
147 %token <string> HOSTNAME
148 %token <string> HOSTNAME_WITH_PORT
149 %token <string> IPADDRESS
150 %token <string> IPADDRESS_WITH_PORT
151 %token <string> STRING
152 %token <string> QUOTED_STRING
153 %token <string> FILE_PATH
154
155 %type <server> server
156 %type <string> string
157 %type <distribution> distribution
158 %type <hash> hash
159 %type <behavior> behavior_boolean
160 %type <behavior> behavior_number
161
162 %%
163
164 begin:
165 statement
166 | begin ' ' statement
167 ;
168
169 statement:
170 expression
171 { }
172 | COMMENT
173 { }
174 | EMPTY_LINE
175 { }
176 | END
177 {
178 context->set_end();
179 YYACCEPT;
180 }
181 | ERROR
182 {
183 context->rc= MEMCACHED_PARSE_USER_ERROR;
184 parser_abort(context, NULL);
185 }
186 | RESET
187 {
188 memcached_reset(context->memc);
189 }
190 | PARSER_DEBUG
191 {
192 yydebug= 1;
193 }
194 | INCLUDE ' ' string
195 {
196 if ((context->rc= memcached_parse_configure_file(context->memc, $3.c_str, $3.length)) != MEMCACHED_SUCCESS)
197 {
198 parser_abort(context, NULL);
199 }
200 }
201 ;
202
203
204 expression:
205 SERVER '=' server
206 {
207 if ((context->rc= memcached_server_add_parsed(context->memc, $3.c_str, $3.length, $3.port, 0)) != MEMCACHED_SUCCESS)
208 {
209 parser_abort(context, NULL);
210 }
211 }
212 | SERVERS_OPTION '=' server_list
213 {
214 }
215 | CONFIGURE_FILE '=' string
216 {
217 memcached_set_configuration_file(context->memc, $3.c_str, $3.length);
218 }
219 | behaviors
220 ;
221
222 behaviors:
223 PREFIX_KEY '=' string
224 {
225 if ((context->rc= memcached_set_prefix_key(context->memc, $3.c_str, $3.length)) != MEMCACHED_SUCCESS)
226 {
227 parser_abort(context, NULL);;
228 }
229 }
230 | DISTRIBUTION '=' distribution
231 {
232 if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $3)) != MEMCACHED_SUCCESS)
233 {
234 parser_abort(context, NULL);;
235 }
236 }
237 | HASH '=' hash
238 {
239 if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_HASH, $3)) != MEMCACHED_SUCCESS)
240 {
241 parser_abort(context, NULL);;
242 }
243 }
244 | KETAMA_HASH '=' hash
245 {
246 if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, $3)) != MEMCACHED_SUCCESS)
247 {
248 parser_abort(context, NULL);;
249 }
250 }
251 | behavior_number '=' NUMBER
252 {
253 if ((context->rc= memcached_behavior_set(context->memc, $1, $3)) != MEMCACHED_SUCCESS)
254 {
255 parser_abort(context, NULL);;
256 }
257 }
258 | behavior_boolean
259 {
260 if ((context->rc= memcached_behavior_set(context->memc, $1, true)) != MEMCACHED_SUCCESS)
261 {
262 parser_abort(context, NULL);;
263 }
264 }
265 | USER_DATA
266 {
267 }
268 ;
269
270 behavior_number:
271 CONNECT_TIMEOUT
272 {
273 $$= MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT;
274 }
275 | IO_MSG_WATERMARK
276 {
277 $$= MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK;
278 }
279 | IO_BYTES_WATERMARK
280 {
281 $$= MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK;
282 }
283 | IO_KEY_PREFETCH
284 {
285 $$= MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH;
286 }
287 | NUMBER_OF_REPLICAS
288 {
289 $$= MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS;
290 }
291 | POLL_TIMEOUT
292 {
293 $$= MEMCACHED_BEHAVIOR_POLL_TIMEOUT;
294 }
295 | RCV_TIMEOUT
296 {
297 $$= MEMCACHED_BEHAVIOR_RCV_TIMEOUT;
298 }
299 | RETRY_TIMEOUT
300 {
301 $$= MEMCACHED_BEHAVIOR_RETRY_TIMEOUT;
302 }
303 | SERVER_FAILURE_LIMIT
304 {
305 $$= MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT;
306 }
307 | SND_TIMEOUT
308 {
309 $$= MEMCACHED_BEHAVIOR_SND_TIMEOUT;
310 }
311 | SOCKET_RECV_SIZE
312 {
313 $$= MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE;
314 }
315 | SOCKET_SEND_SIZE
316 {
317 $$= MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE;
318 }
319 ;
320
321 behavior_boolean:
322 AUTO_EJECT_HOSTS
323 {
324 $$= MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS;
325 }
326 | BINARY_PROTOCOL
327 {
328 $$= MEMCACHED_BEHAVIOR_BINARY_PROTOCOL;
329 }
330 | BUFFER_REQUESTS
331 {
332 $$= MEMCACHED_BEHAVIOR_BUFFER_REQUESTS;
333 }
334 | CACHE_LOOKUPS
335 {
336 $$= MEMCACHED_BEHAVIOR_CACHE_LOOKUPS;
337 }
338 | _CORK
339 {
340 $$= MEMCACHED_BEHAVIOR_CORK;
341 }
342 | HASH_WITH_PREFIX_KEY
343 {
344 $$= MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY;
345 }
346 | KETAMA
347 {
348 $$= MEMCACHED_BEHAVIOR_KETAMA;
349 }
350 | KETAMA_WEIGHTED
351 {
352 $$= MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED;
353 }
354 | NOREPLY
355 {
356 $$= MEMCACHED_BEHAVIOR_NOREPLY;
357 }
358 | RANDOMIZE_REPLICA_READ
359 {
360 $$= MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ;
361 }
362 | SORT_HOSTS
363 {
364 $$= MEMCACHED_BEHAVIOR_SORT_HOSTS;
365 }
366 | SUPPORT_CAS
367 {
368 $$= MEMCACHED_BEHAVIOR_SUPPORT_CAS;
369 }
370 | _TCP_NODELAY
371 {
372 $$= MEMCACHED_BEHAVIOR_TCP_NODELAY;
373 }
374 | _TCP_KEEPALIVE
375 {
376 $$= MEMCACHED_BEHAVIOR_TCP_KEEPALIVE;
377 }
378 | _TCP_KEEPIDLE
379 {
380 $$= MEMCACHED_BEHAVIOR_TCP_KEEPIDLE;
381 }
382 | USE_UDP
383 {
384 $$= MEMCACHED_BEHAVIOR_USE_UDP;
385 }
386 | VERIFY_KEY
387 {
388 $$= MEMCACHED_BEHAVIOR_VERIFY_KEY;
389 }
390
391
392 server_list:
393 server
394 {
395 if ((context->rc= memcached_server_add_parsed(context->memc, $1.c_str, $1.length, $1.port, 0)) != MEMCACHED_SUCCESS)
396 {
397 parser_abort(context, NULL);;
398 }
399 }
400 | server_list ',' server
401 {
402 if ((context->rc= memcached_server_add_parsed(context->memc, $3.c_str, $3.length, $3.port, 0)) != MEMCACHED_SUCCESS)
403 {
404 parser_abort(context, NULL);;
405 }
406 }
407 ;
408
409 server:
410 HOSTNAME_WITH_PORT NUMBER
411 {
412 $$.c_str= $1.c_str;
413 $$.length= $1.length -1; // -1 to remove :
414 $$.port= $2;
415 }
416 | HOSTNAME
417 {
418 $$.c_str= $1.c_str;
419 $$.length= $1.length;
420 $$.port= MEMCACHED_DEFAULT_PORT;
421 }
422 | STRING /* a match can be against "localhost" which is just a string */
423 {
424 $$.c_str= $1.c_str;
425 $$.length= $1.length;
426 $$.port= MEMCACHED_DEFAULT_PORT;
427 }
428 | IPADDRESS_WITH_PORT NUMBER
429 {
430 $$.c_str= $1.c_str;
431 $$.length= $1.length -1; // -1 to remove :
432 $$.port= $2;
433 }
434 | IPADDRESS
435 {
436 $$.c_str= $1.c_str;
437 $$.length= $1.length;
438 $$.port= MEMCACHED_DEFAULT_PORT;
439 }
440 ;
441
442 hash:
443 MD5
444 {
445 $$= MEMCACHED_HASH_MD5;
446 }
447 | CRC
448 {
449 $$= MEMCACHED_HASH_CRC;
450 }
451 | FNV1_64
452 {
453 $$= MEMCACHED_HASH_FNV1_64;
454 }
455 | FNV1A_64
456 {
457 $$= MEMCACHED_HASH_FNV1A_64;
458 }
459 | FNV1_32
460 {
461 $$= MEMCACHED_HASH_FNV1_32;
462 }
463 | FNV1A_32
464 {
465 $$= MEMCACHED_HASH_FNV1A_32;
466 }
467 | HSIEH
468 {
469 $$= MEMCACHED_HASH_HSIEH;
470 }
471 | MURMUR
472 {
473 $$= MEMCACHED_HASH_MURMUR;
474 }
475 | JENKINS
476 {
477 $$= MEMCACHED_HASH_JENKINS;
478 }
479 ;
480
481 string:
482 STRING
483 {
484 $$= $1;
485 }
486 | QUOTED_STRING
487 {
488 $$.c_str= $1.c_str +1; // +1 to move use passed the initial quote
489 $$.length= $1.length -1; // -1 removes the end quote
490 }
491 ;
492
493 distribution:
494 CONSISTENT
495 {
496 $$= MEMCACHED_DISTRIBUTION_CONSISTENT;
497 }
498 | MODULA
499 {
500 $$= MEMCACHED_DISTRIBUTION_MODULA;
501 }
502 | RANDOM
503 {
504 $$= MEMCACHED_DISTRIBUTION_RANDOM;
505 }
506 ;