Fix UUID and issue on older Debian systems.
[awesomized/libmemcached] / libmemcached / csl / parser.yy
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * Libmemcached library
4 *
5 * Copyright (C) 2012 Data Differential, http://datadifferential.com/
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following disclaimer
16 * in the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * * The names of its contributors may not be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 */
36
37 %error-verbose
38 %debug
39 %defines
40 %expect 0
41 %output "libmemcached/csl/parser.cc"
42 %defines "libmemcached/csl/parser.h"
43 %lex-param { yyscan_t *scanner }
44 %name-prefix="config_"
45 %parse-param { Context *context }
46 %parse-param { yyscan_t *scanner }
47 %pure-parser
48 %require "2.4"
49 %start begin
50 %verbose
51
52 %{
53
54 #include <libmemcached/csl/common.h>
55 #include <libmemcached/options.hpp>
56
57 #include <libmemcached/csl/context.h>
58 #include <libmemcached/csl/symbol.h>
59 #include <libmemcached/csl/scanner.h>
60
61 #ifndef __INTEL_COMPILER
62 #pragma GCC diagnostic ignored "-Wold-style-cast"
63 #endif
64
65 #ifndef __INTEL_COMPILER
66 #pragma GCC diagnostic ignored "-Wlogical-op"
67 #endif
68
69 int conf_lex(YYSTYPE* lvalp, void* scanner);
70
71 #define select_yychar(__context) yychar == UNKNOWN ? ( (__context)->previous_token == END ? UNKNOWN : (__context)->previous_token ) : yychar
72
73 #define stryytname(__yytokentype) ((__yytokentype) < YYNTOKENS ) ? yytname[(__yytokentype)] : ""
74
75 #define parser_abort(__context, __error_message) do { (__context)->abort((__error_message), yytokentype(select_yychar(__context)), stryytname(YYTRANSLATE(select_yychar(__context)))); YYABORT; } while (0)
76
77 // This is bison calling error.
78 inline void __config_error(Context *context, yyscan_t *scanner, const char *error, int last_token, const char *last_token_str)
79 {
80 if (not context->end())
81 {
82 context->error(error, yytokentype(last_token), last_token_str);
83 }
84 else
85 {
86 context->error(error, yytokentype(last_token), last_token_str);
87 }
88 }
89
90 #define config_error(__context, __scanner, __error_msg) do { __config_error((__context), (__scanner), (__error_msg), select_yychar(__context), stryytname(YYTRANSLATE(select_yychar(__context)))); } while (0)
91
92
93 %}
94
95 %token COMMENT
96 %token END
97 %token ERROR
98 %token RESET
99 %token PARSER_DEBUG
100 %token INCLUDE
101 %token CONFIGURE_FILE
102 %token EMPTY_LINE
103 %token SERVER
104 %token SOCKET
105 %token SERVERS
106 %token SERVERS_OPTION
107 %token UNKNOWN_OPTION
108 %token UNKNOWN
109
110 /* All behavior options */
111 %token BINARY_PROTOCOL
112 %token BUFFER_REQUESTS
113 %token CONNECT_TIMEOUT
114 %token DISTRIBUTION
115 %token HASH
116 %token HASH_WITH_NAMESPACE
117 %token IO_BYTES_WATERMARK
118 %token IO_KEY_PREFETCH
119 %token IO_MSG_WATERMARK
120 %token KETAMA_HASH
121 %token KETAMA_WEIGHTED
122 %token NOREPLY
123 %token NUMBER_OF_REPLICAS
124 %token POLL_TIMEOUT
125 %token RANDOMIZE_REPLICA_READ
126 %token RCV_TIMEOUT
127 %token REMOVE_FAILED_SERVERS
128 %token RETRY_TIMEOUT
129 %token SND_TIMEOUT
130 %token SOCKET_RECV_SIZE
131 %token SOCKET_SEND_SIZE
132 %token SORT_HOSTS
133 %token SUPPORT_CAS
134 %token USER_DATA
135 %token USE_UDP
136 %token VERIFY_KEY
137 %token _TCP_KEEPALIVE
138 %token _TCP_KEEPIDLE
139 %token _TCP_NODELAY
140 %token FETCH_VERSION
141
142 /* Callbacks */
143 %token NAMESPACE
144
145 /* Pool */
146 %token POOL_MIN
147 %token POOL_MAX
148
149 /* Hash types */
150 %token MD5
151 %token CRC
152 %token FNV1_64
153 %token FNV1A_64
154 %token FNV1_32
155 %token FNV1A_32
156 %token HSIEH
157 %token MURMUR
158 %token JENKINS
159
160 /* Distributions */
161 %token CONSISTENT
162 %token MODULA
163 %token RANDOM
164
165 /* Boolean values */
166 %token <boolean> TRUE
167 %token <boolean> FALSE
168
169 %nonassoc ','
170 %nonassoc '='
171
172 %token <number> FLOAT
173 %token <number> NUMBER
174 %token <number> PORT
175 %token <number> WEIGHT_START
176 %token <server> IPADDRESS
177 %token <server> HOSTNAME
178 %token <string> STRING
179 %token <string> QUOTED_STRING
180 %token <string> FILE_PATH
181
182 %type <behavior> behavior_boolean
183 %type <behavior> behavior_number
184 %type <distribution> distribution
185 %type <hash> hash
186 %type <number> optional_port
187 %type <number> optional_weight
188 %type <string> string
189
190 %%
191
192 begin:
193 statement
194 | begin ' ' statement
195 ;
196
197 statement:
198 expression
199 { }
200 | COMMENT
201 { }
202 | EMPTY_LINE
203 { }
204 | END
205 {
206 context->set_end();
207 YYACCEPT;
208 }
209 | ERROR
210 {
211 context->rc= MEMCACHED_PARSE_USER_ERROR;
212 parser_abort(context, "ERROR called directly");
213 }
214 | RESET
215 {
216 memcached_reset(context->memc);
217 }
218 | PARSER_DEBUG
219 {
220 yydebug= 1;
221 }
222 | INCLUDE ' ' string
223 {
224 if ((context->rc= memcached_parse_configure_file(*context->memc, $3.c_str, $3.size)) != MEMCACHED_SUCCESS)
225 {
226 parser_abort(context, "Failed to parse configuration file");
227 }
228 }
229 ;
230
231
232 expression:
233 SERVER HOSTNAME optional_port optional_weight
234 {
235 if (memcached_failed(context->rc= memcached_server_add_with_weight(context->memc, $2.c_str, $3, uint32_t($4))))
236 {
237 char buffer[1024];
238 snprintf(buffer, sizeof(buffer), "Failed to add server: %s:%u", $2.c_str, uint32_t($3));
239 parser_abort(context, buffer);
240 }
241 context->unset_server();
242 }
243 | SERVER IPADDRESS optional_port optional_weight
244 {
245 if (memcached_failed(context->rc= memcached_server_add_with_weight(context->memc, $2.c_str, $3, uint32_t($4))))
246 {
247 char buffer[1024];
248 snprintf(buffer, sizeof(buffer), "Failed to add server: %s:%u", $2.c_str, uint32_t($3));
249 parser_abort(context, buffer);
250 }
251 context->unset_server();
252 }
253 | SOCKET string optional_weight
254 {
255 if (memcached_failed(context->rc= memcached_server_add_unix_socket_with_weight(context->memc, $2.c_str, uint32_t($3))))
256 {
257 char buffer[1024];
258 snprintf(buffer, sizeof(buffer), "Failed to add socket: %s", $2.c_str);
259 parser_abort(context, buffer);
260 }
261 }
262 | CONFIGURE_FILE string
263 {
264 memcached_set_configuration_file(context->memc, $2.c_str, $2.size);
265 }
266 | POOL_MIN NUMBER
267 {
268 context->memc->configure.initial_pool_size= uint32_t($2);
269 }
270 | POOL_MAX NUMBER
271 {
272 context->memc->configure.max_pool_size= uint32_t($2);
273 }
274 | behaviors
275 ;
276
277 behaviors:
278 NAMESPACE string
279 {
280 if (memcached_callback_get(context->memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL))
281 {
282 parser_abort(context, "--NAMESPACE can only be called once");
283 }
284
285 if ((context->rc= memcached_set_namespace(context->memc, $2.c_str, $2.size)) != MEMCACHED_SUCCESS)
286 {
287 parser_abort(context, memcached_last_error_message(context->memc));
288 }
289 }
290 | FETCH_VERSION
291 {
292 memcached_flag(*context->memc, MEMCACHED_FLAG_IS_FETCHING_VERSION, true);
293 }
294 | DISTRIBUTION distribution
295 {
296 // Check to see if DISTRIBUTION has already been set
297 if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $2)) != MEMCACHED_SUCCESS)
298 {
299 parser_abort(context, "--DISTRIBUTION can only be called once");
300 }
301
302 if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $2)) != MEMCACHED_SUCCESS)
303 {
304 parser_abort(context, memcached_last_error_message(context->memc));;
305 }
306 }
307 | DISTRIBUTION distribution ',' hash
308 {
309 // Check to see if DISTRIBUTION has already been set
310 if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $2)) != MEMCACHED_SUCCESS)
311 {
312 parser_abort(context, "--DISTRIBUTION can only be called once");
313 }
314
315 if ((context->rc= memcached_behavior_set_distribution_hash(context->memc, $4)) != MEMCACHED_SUCCESS)
316 {
317 parser_abort(context, "Unable to set the hash for the DISTRIBUTION requested");
318 }
319 }
320 | HASH hash
321 {
322 if (context->set_hash($2) == false)
323 {
324 parser_abort(context, "--HASH can only be set once");
325 }
326 }
327 | behavior_number NUMBER
328 {
329 if ((context->rc= memcached_behavior_set(context->memc, $1, $2)) != MEMCACHED_SUCCESS)
330 {
331 parser_abort(context, "Unable to set behavior");
332 }
333 }
334 | behavior_boolean
335 {
336 if ((context->rc= memcached_behavior_set(context->memc, $1, true)) != MEMCACHED_SUCCESS)
337 {
338 char buffer[1024];
339 snprintf(buffer, sizeof(buffer), "Could not set: %s", libmemcached_string_behavior($1));
340 parser_abort(context, buffer);
341 }
342 }
343 | USER_DATA
344 {
345 }
346 ;
347
348 behavior_number:
349 REMOVE_FAILED_SERVERS
350 {
351 $$= MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS;
352 }
353 | CONNECT_TIMEOUT
354 {
355 $$= MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT;
356 }
357 | IO_MSG_WATERMARK
358 {
359 $$= MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK;
360 }
361 | IO_BYTES_WATERMARK
362 {
363 $$= MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK;
364 }
365 | IO_KEY_PREFETCH
366 {
367 $$= MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH;
368 }
369 | NUMBER_OF_REPLICAS
370 {
371 $$= MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS;
372 }
373 | POLL_TIMEOUT
374 {
375 $$= MEMCACHED_BEHAVIOR_POLL_TIMEOUT;
376 }
377 | RCV_TIMEOUT
378 {
379 $$= MEMCACHED_BEHAVIOR_RCV_TIMEOUT;
380 }
381 | RETRY_TIMEOUT
382 {
383 $$= MEMCACHED_BEHAVIOR_RETRY_TIMEOUT;
384 }
385 | SND_TIMEOUT
386 {
387 $$= MEMCACHED_BEHAVIOR_SND_TIMEOUT;
388 }
389 | SOCKET_RECV_SIZE
390 {
391 $$= MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE;
392 }
393 | SOCKET_SEND_SIZE
394 {
395 $$= MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE;
396 }
397 ;
398
399 behavior_boolean:
400 BINARY_PROTOCOL
401 {
402 $$= MEMCACHED_BEHAVIOR_BINARY_PROTOCOL;
403 }
404 | BUFFER_REQUESTS
405 {
406 $$= MEMCACHED_BEHAVIOR_BUFFER_REQUESTS;
407 }
408 | HASH_WITH_NAMESPACE
409 {
410 $$= MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY;
411 }
412 | NOREPLY
413 {
414 $$= MEMCACHED_BEHAVIOR_NOREPLY;
415 }
416 | RANDOMIZE_REPLICA_READ
417 {
418 $$= MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ;
419 }
420 | SORT_HOSTS
421 {
422 $$= MEMCACHED_BEHAVIOR_SORT_HOSTS;
423 }
424 | SUPPORT_CAS
425 {
426 $$= MEMCACHED_BEHAVIOR_SUPPORT_CAS;
427 }
428 | _TCP_NODELAY
429 {
430 $$= MEMCACHED_BEHAVIOR_TCP_NODELAY;
431 }
432 | _TCP_KEEPALIVE
433 {
434 $$= MEMCACHED_BEHAVIOR_TCP_KEEPALIVE;
435 }
436 | _TCP_KEEPIDLE
437 {
438 $$= MEMCACHED_BEHAVIOR_TCP_KEEPIDLE;
439 }
440 | USE_UDP
441 {
442 $$= MEMCACHED_BEHAVIOR_USE_UDP;
443 }
444 | VERIFY_KEY
445 {
446 $$= MEMCACHED_BEHAVIOR_VERIFY_KEY;
447 }
448
449
450 optional_port:
451 { $$= MEMCACHED_DEFAULT_PORT;}
452 | PORT
453 { };
454 ;
455
456 optional_weight:
457 { $$= 1; }
458 | WEIGHT_START
459 { }
460 ;
461
462 hash:
463 MD5
464 {
465 $$= MEMCACHED_HASH_MD5;
466 }
467 | CRC
468 {
469 $$= MEMCACHED_HASH_CRC;
470 }
471 | FNV1_64
472 {
473 $$= MEMCACHED_HASH_FNV1_64;
474 }
475 | FNV1A_64
476 {
477 $$= MEMCACHED_HASH_FNV1A_64;
478 }
479 | FNV1_32
480 {
481 $$= MEMCACHED_HASH_FNV1_32;
482 }
483 | FNV1A_32
484 {
485 $$= MEMCACHED_HASH_FNV1A_32;
486 }
487 | HSIEH
488 {
489 $$= MEMCACHED_HASH_HSIEH;
490 }
491 | MURMUR
492 {
493 $$= MEMCACHED_HASH_MURMUR;
494 }
495 | JENKINS
496 {
497 $$= MEMCACHED_HASH_JENKINS;
498 }
499 ;
500
501 string:
502 STRING
503 {
504 $$= $1;
505 }
506 | QUOTED_STRING
507 {
508 $$= $1;
509 }
510 ;
511
512 distribution:
513 CONSISTENT
514 {
515 $$= MEMCACHED_DISTRIBUTION_CONSISTENT;
516 }
517 | MODULA
518 {
519 $$= MEMCACHED_DISTRIBUTION_MODULA;
520 }
521 | RANDOM
522 {
523 $$= MEMCACHED_DISTRIBUTION_RANDOM;
524 }
525 ;
526
527 %%
528
529 void Context::start()
530 {
531 config_parse(this, (void **)scanner);
532 }
533