1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3 * Libmemcached Scanner and Parser
5 * Copyright (C) 2011 DataDifferental, http://datadifferential.com
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.
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.
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/>.
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 }
46 #include <libmemcached/options/context.h>
47 #include <libmemcached/options/string.h>
48 #include <libmemcached/options/symbol.h>
50 #pragma GCC diagnostic ignored "-Wold-style-cast"
51 #include <libmemcached/options/scanner.h>
53 int libmemcached_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner);
55 #define parser_abort(A, B) do { parser_abort_func((A), (B)); YYABORT; } while (0)
57 inline void parser_abort_func(Context *context, const char *error)
60 if (context->rc == MEMCACHED_SUCCESS)
61 context->rc= MEMCACHED_PARSE_ERROR;
63 std::string error_message;
64 error_message+= "Error occured while parsing: ";
65 error_message+= context->begin;
67 if (context->rc == MEMCACHED_PARSE_ERROR and error)
69 error_message+= error;
73 error_message+= memcached_strerror(NULL, context->rc);
77 memcached_set_error_string(context->memc, context->rc, error_message.c_str(), error_message.size());
80 inline void libmemcached_error(YYLTYPE *locp, Context *context, yyscan_t *scanner, const char *error)
82 if (not context->end())
83 parser_abort_func(context, error);
86 int libmemcached_parse(Context*, yyscan_t *);
89 libmemcached_parse(this, scanner);
100 %token CONFIGURE_FILE
104 %token SERVERS_OPTION
105 %token UNKNOWN_OPTION
108 /* All behavior options */
109 %token AUTO_EJECT_HOSTS
110 %token BINARY_PROTOCOL
111 %token BUFFER_REQUESTS
113 %token CONNECT_TIMEOUT
117 %token HASH_WITH_PREFIX_KEY
118 %token IO_BYTES_WATERMARK
119 %token IO_KEY_PREFETCH
120 %token IO_MSG_WATERMARK
123 %token KETAMA_WEIGHTED
125 %token NUMBER_OF_REPLICAS
127 %token RANDOMIZE_REPLICA_READ
130 %token SERVER_FAILURE_LIMIT
132 %token SOCKET_RECV_SIZE
133 %token SOCKET_SEND_SIZE
137 %token _TCP_KEEPALIVE
163 %token <boolean> TRUE
164 %token <boolean> FALSE
169 %token <number> NUMBER
170 %token <number> FLOAT
171 %token <string> HOSTNAME
172 %token <string> HOSTNAME_WITH_PORT
173 %token <string> IPADDRESS
174 %token <string> IPADDRESS_WITH_PORT
175 %token <string> STRING
176 %token <string> QUOTED_STRING
177 %token <string> FILE_PATH
179 %type <server> server
180 %type <string> string
181 %type <distribution> distribution
183 %type <behavior> behavior_boolean
184 %type <behavior> behavior_number
190 | begin ' ' statement
207 context->rc= MEMCACHED_PARSE_USER_ERROR;
208 parser_abort(context, NULL);
212 memcached_reset(context->memc);
220 if ((context->rc= memcached_parse_configure_file(context->memc, $3.c_str, $3.length)) != MEMCACHED_SUCCESS)
222 parser_abort(context, NULL);
231 if ((context->rc= memcached_server_add_parsed(context->memc, $3.c_str, $3.length, $3.port, 0)) != MEMCACHED_SUCCESS)
233 parser_abort(context, NULL);
236 | SERVERS_OPTION '=' server_list
239 | CONFIGURE_FILE '=' string
241 memcached_set_configuration_file(context->memc, $3.c_str, $3.length);
247 PREFIX_KEY '=' string
249 if ((context->rc= memcached_callback_set(context->memc, MEMCACHED_CALLBACK_PREFIX_KEY, std::string($3.c_str, $3.length).c_str())) != MEMCACHED_SUCCESS)
251 parser_abort(context, NULL);;
254 | DISTRIBUTION '=' distribution
256 if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $3)) != MEMCACHED_SUCCESS)
258 parser_abort(context, NULL);;
263 if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_HASH, $3)) != MEMCACHED_SUCCESS)
265 parser_abort(context, NULL);;
268 | KETAMA_HASH '=' hash
270 if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, $3)) != MEMCACHED_SUCCESS)
272 parser_abort(context, NULL);;
275 | behavior_number '=' NUMBER
277 if ((context->rc= memcached_behavior_set(context->memc, $1, $3)) != MEMCACHED_SUCCESS)
279 parser_abort(context, NULL);;
284 if ((context->rc= memcached_behavior_set(context->memc, $1, true)) != MEMCACHED_SUCCESS)
286 parser_abort(context, NULL);;
297 $$= MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT;
301 $$= MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK;
305 $$= MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK;
309 $$= MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH;
313 $$= MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS;
317 $$= MEMCACHED_BEHAVIOR_POLL_TIMEOUT;
321 $$= MEMCACHED_BEHAVIOR_RCV_TIMEOUT;
325 $$= MEMCACHED_BEHAVIOR_RETRY_TIMEOUT;
327 | SERVER_FAILURE_LIMIT
329 $$= MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT;
333 $$= MEMCACHED_BEHAVIOR_SND_TIMEOUT;
337 $$= MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE;
341 $$= MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE;
348 $$= MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS;
352 $$= MEMCACHED_BEHAVIOR_BINARY_PROTOCOL;
356 $$= MEMCACHED_BEHAVIOR_BUFFER_REQUESTS;
360 $$= MEMCACHED_BEHAVIOR_CACHE_LOOKUPS;
364 $$= MEMCACHED_BEHAVIOR_CORK;
366 | HASH_WITH_PREFIX_KEY
368 $$= MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY;
372 $$= MEMCACHED_BEHAVIOR_KETAMA;
376 $$= MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED;
380 $$= MEMCACHED_BEHAVIOR_NOREPLY;
382 | RANDOMIZE_REPLICA_READ
384 $$= MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ;
388 $$= MEMCACHED_BEHAVIOR_SORT_HOSTS;
392 $$= MEMCACHED_BEHAVIOR_SUPPORT_CAS;
396 $$= MEMCACHED_BEHAVIOR_TCP_NODELAY;
400 $$= MEMCACHED_BEHAVIOR_TCP_KEEPALIVE;
404 $$= MEMCACHED_BEHAVIOR_TCP_KEEPIDLE;
408 $$= MEMCACHED_BEHAVIOR_USE_UDP;
412 $$= MEMCACHED_BEHAVIOR_VERIFY_KEY;
419 if ((context->rc= memcached_server_add_parsed(context->memc, $1.c_str, $1.length, $1.port, 0)) != MEMCACHED_SUCCESS)
421 parser_abort(context, NULL);;
424 | server_list ',' server
426 if ((context->rc= memcached_server_add_parsed(context->memc, $3.c_str, $3.length, $3.port, 0)) != MEMCACHED_SUCCESS)
428 parser_abort(context, NULL);;
434 HOSTNAME_WITH_PORT NUMBER
437 $$.length= $1.length -1; // -1 to remove :
443 $$.length= $1.length;
444 $$.port= MEMCACHED_DEFAULT_PORT;
446 | STRING /* a match can be against "localhost" which is just a string */
449 $$.length= $1.length;
450 $$.port= MEMCACHED_DEFAULT_PORT;
452 | IPADDRESS_WITH_PORT NUMBER
455 $$.length= $1.length -1; // -1 to remove :
461 $$.length= $1.length;
462 $$.port= MEMCACHED_DEFAULT_PORT;
469 $$= MEMCACHED_HASH_MD5;
473 $$= MEMCACHED_HASH_CRC;
477 $$= MEMCACHED_HASH_FNV1_64;
481 $$= MEMCACHED_HASH_FNV1A_64;
485 $$= MEMCACHED_HASH_FNV1_32;
489 $$= MEMCACHED_HASH_FNV1A_32;
493 $$= MEMCACHED_HASH_HSIEH;
497 $$= MEMCACHED_HASH_MURMUR;
501 $$= MEMCACHED_HASH_JENKINS;
512 $$.c_str= $1.c_str +1; // +1 to move use passed the initial quote
513 $$.length= $1.length -1; // -1 removes the end quote
520 $$= MEMCACHED_DISTRIBUTION_CONSISTENT;
524 $$= MEMCACHED_DISTRIBUTION_MODULA;
528 $$= MEMCACHED_DISTRIBUTION_RANDOM;