X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Foptions%2Fparser.yy;h=8e87230ade8c10e534d2d3c8db618ea31c3948c3;hb=d8dedbd561c7cb57daf4192fe57ce5e205bcadd7;hp=ae7e6d5f38d1971a185ab9bf236bc55151b607d4;hpb=10f3d6bf1bc11c235779ae735f30758cfb035686;p=awesomized%2Flibmemcached diff --git a/libmemcached/options/parser.yy b/libmemcached/options/parser.yy index ae7e6d5f..8e87230a 100644 --- a/libmemcached/options/parser.yy +++ b/libmemcached/options/parser.yy @@ -1,141 +1,468 @@ /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * - * Libmemcached library * - * Copyright (C) 2011 Data Differential, http://datadifferential.com/ - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * The names of its contributors may not be used to endorse or - * promote products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Libmemcached Scanner and Parser * + * Copyright (C) 2011 DataDifferental, http://datadifferential.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ +%error-verbose +%debug +%defines +%expect 0 +%output "libmemcached/options/parser.cc" +%defines "libmemcached/options/parser.h" +%lex-param { yyscan_t *scanner } +%name-prefix="config_" +%parse-param { Context *context } +%parse-param { yyscan_t *scanner } +%pure-parser +%require "2.2" +%start begin +%verbose + %{ +#include + #include -#include -#include -#include +#include +#include + +#include #include +#include #pragma GCC diagnostic ignored "-Wold-style-cast" -#include -inline int libmemcached_error(YYLTYPE *locp, type_st *parser, yyscan_t *scanner, const char *str) +int conf_lex(YYSTYPE* lvalp, void* scanner); + +#define parser_abort(A, B) do { (A)->abort((B)); YYABORT; } while (0) + +inline void config_error(Context *context, yyscan_t *scanner, const char *error) { - std::cerr << str << std::endl; - return 0; + if (not context->end()) + context->abort(error); } - %} -%error-verbose -%debug -%defines -%expect 0 -%output "libmemcached/options/parser.cc" -%defines "libmemcached/options/parser.h" -%lex-param { yyscan_t *scanner } -%name-prefix="libmemcached_" -%parse-param { type_st *parser } -%parse-param { yyscan_t *scanner } -%locations -%pure-parser -%require "2.2" -%start statement -%verbose - -%token EQ +%token COMMENT +%token END +%token ERROR +%token RESET +%token PARSER_DEBUG +%token INCLUDE +%token CONFIGURE_FILE +%token EMPTY_LINE %token SERVER %token SERVERS -%token TCPNODELAY +%token SERVERS_OPTION +%token UNKNOWN_OPTION %token UNKNOWN + +/* All behavior options */ +%token BINARY_PROTOCOL +%token BUFFER_REQUESTS +%token CONNECT_TIMEOUT +%token DISTRIBUTION +%token HASH +%token HASH_WITH_NAMESPACE +%token IO_BYTES_WATERMARK +%token IO_KEY_PREFETCH +%token IO_MSG_WATERMARK +%token KETAMA_HASH +%token KETAMA_WEIGHTED +%token NOREPLY +%token NUMBER_OF_REPLICAS +%token POLL_TIMEOUT +%token RANDOMIZE_REPLICA_READ +%token RCV_TIMEOUT +%token REMOVE_FAILED_SERVERS +%token RETRY_TIMEOUT +%token SND_TIMEOUT +%token SOCKET_RECV_SIZE +%token SOCKET_SEND_SIZE +%token SORT_HOSTS +%token SUPPORT_CAS +%token USER_DATA +%token USE_UDP %token VERIFY_KEY -%token COMMA +%token _TCP_KEEPALIVE +%token _TCP_KEEPIDLE +%token _TCP_NODELAY + +/* Callbacks */ +%token NAMESPACE + +/* Pool */ +%token POOL_MIN +%token POOL_MAX + +/* Hash types */ +%token MD5 +%token CRC +%token FNV1_64 +%token FNV1A_64 +%token FNV1_32 +%token FNV1A_32 +%token HSIEH +%token MURMUR +%token JENKINS + +/* Distributions */ +%token CONSISTENT +%token MODULA +%token RANDOM + +/* Boolean values */ +%token TRUE +%token FALSE + +%nonassoc ',' +%nonassoc '=' -%token NUMBER %token FLOAT -%token IDENTIFIER -%token SERVER_WITH_PORT +%token NUMBER +%token PORT +%token WEIGHT_START +%token IPADDRESS +%token HOSTNAME +%token STRING +%token QUOTED_STRING +%token FILE_PATH -%type server +%type behavior_boolean +%type behavior_number +%type distribution +%type hash +%type optional_port +%type optional_weight +%type string %% +begin: + statement + | begin ' ' statement + ; + statement: - expression + expression + { } + | COMMENT { } - | statement expression + | EMPTY_LINE { } + | END + { + context->set_end(); + YYACCEPT; + } + | ERROR + { + context->rc= MEMCACHED_PARSE_USER_ERROR; + parser_abort(context, NULL); + } + | RESET + { + memcached_reset(context->memc); + } + | PARSER_DEBUG + { + yydebug= 1; + } + | INCLUDE ' ' string + { + if ((context->rc= memcached_parse_configure_file(*context->memc, $3.c_str, $3.size)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL); + } + } ; expression: - SERVER EQ server - { - (void) memcached_server_add(parser->memc, $3.c_str, $3.port); + SERVER HOSTNAME optional_port optional_weight + { + if (memcached_failed(context->rc= memcached_server_add_with_weight(context->memc, $2.c_str, $3, $4))) + { + parser_abort(context, NULL); + } + context->unset_server(); + } + | SERVER IPADDRESS optional_port optional_weight + { + if (memcached_failed(context->rc= memcached_server_add_with_weight(context->memc, $2.c_str, $3, $4))) + { + parser_abort(context, NULL); + } + context->unset_server(); + } + | CONFIGURE_FILE string + { + memcached_set_configuration_file(context->memc, $2.c_str, $2.size); + } + | POOL_MIN NUMBER + { + context->memc->configure.initial_pool_size= $2; + } + | POOL_MAX NUMBER + { + context->memc->configure.max_pool_size= $2; + } + | behaviors + ; + +behaviors: + NAMESPACE string + { + if ((context->rc= memcached_set_namespace(context->memc, $2.c_str, $2.size)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL);; + } + } + | DISTRIBUTION distribution + { + if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $2)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL);; + } + } + | DISTRIBUTION distribution ',' hash + { + if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $2)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL);; + } + if ((context->rc= memcached_behavior_set_distribution_hash(context->memc, $4)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL);; + } + } + | HASH hash + { + if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_HASH, $2)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL);; + } + } + | behavior_number NUMBER + { + if ((context->rc= memcached_behavior_set(context->memc, $1, $2)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL);; + } + } + | behavior_boolean + { + if ((context->rc= memcached_behavior_set(context->memc, $1, true)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL);; + } } - | SERVERS EQ server_list + | USER_DATA + { + } + ; + +behavior_number: + REMOVE_FAILED_SERVERS + { + $$= MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS; + } + | CONNECT_TIMEOUT + { + $$= MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT; + } + | IO_MSG_WATERMARK + { + $$= MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK; + } + | IO_BYTES_WATERMARK + { + $$= MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK; + } + | IO_KEY_PREFETCH + { + $$= MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH; + } + | NUMBER_OF_REPLICAS + { + $$= MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS; + } + | POLL_TIMEOUT + { + $$= MEMCACHED_BEHAVIOR_POLL_TIMEOUT; + } + | RCV_TIMEOUT + { + $$= MEMCACHED_BEHAVIOR_RCV_TIMEOUT; + } + | RETRY_TIMEOUT + { + $$= MEMCACHED_BEHAVIOR_RETRY_TIMEOUT; + } + | SND_TIMEOUT + { + $$= MEMCACHED_BEHAVIOR_SND_TIMEOUT; + } + | SOCKET_RECV_SIZE + { + $$= MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE; + } + | SOCKET_SEND_SIZE + { + $$= MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE; + } + ; + +behavior_boolean: + BINARY_PROTOCOL + { + $$= MEMCACHED_BEHAVIOR_BINARY_PROTOCOL; + } + | BUFFER_REQUESTS + { + $$= MEMCACHED_BEHAVIOR_BUFFER_REQUESTS; + } + | HASH_WITH_NAMESPACE + { + $$= MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY; + } + | NOREPLY + { + $$= MEMCACHED_BEHAVIOR_NOREPLY; + } + | RANDOMIZE_REPLICA_READ + { + $$= MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ; + } + | SORT_HOSTS + { + $$= MEMCACHED_BEHAVIOR_SORT_HOSTS; + } + | SUPPORT_CAS + { + $$= MEMCACHED_BEHAVIOR_SUPPORT_CAS; + } + | _TCP_NODELAY + { + $$= MEMCACHED_BEHAVIOR_TCP_NODELAY; + } + | _TCP_KEEPALIVE + { + $$= MEMCACHED_BEHAVIOR_TCP_KEEPALIVE; + } + | _TCP_KEEPIDLE + { + $$= MEMCACHED_BEHAVIOR_TCP_KEEPIDLE; + } + | USE_UDP + { + $$= MEMCACHED_BEHAVIOR_USE_UDP; + } + | VERIFY_KEY + { + $$= MEMCACHED_BEHAVIOR_VERIFY_KEY; + } + + +optional_port: + { $$= MEMCACHED_DEFAULT_PORT;} + | PORT + { }; + ; + +optional_weight: + { $$= 1; } + | WEIGHT_START { } - | TCPNODELAY + ; + +hash: + MD5 + { + $$= MEMCACHED_HASH_MD5; + } + | CRC + { + $$= MEMCACHED_HASH_CRC; + } + | FNV1_64 + { + $$= MEMCACHED_HASH_FNV1_64; + } + | FNV1A_64 + { + $$= MEMCACHED_HASH_FNV1A_64; + } + | FNV1_32 + { + $$= MEMCACHED_HASH_FNV1_32; + } + | FNV1A_32 + { + $$= MEMCACHED_HASH_FNV1A_32; + } + | HSIEH + { + $$= MEMCACHED_HASH_HSIEH; + } + | MURMUR { - memcached_behavior_set(parser->memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true); + $$= MEMCACHED_HASH_MURMUR; } - | VERIFY_KEY + | JENKINS { - memcached_behavior_set(parser->memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, true); + $$= MEMCACHED_HASH_JENKINS; } ; -server_list: - server +string: + STRING { - (void) memcached_server_add(parser->memc, $1.c_str, $1.port); + $$= $1; } - | server_list COMMA server + | QUOTED_STRING { - (void) memcached_server_add(parser->memc, $3.c_str, $3.port); + $$.c_str= $1.c_str +1; // +1 to move use passed the initial quote + $$.size= $1.size -2; // -2 removes the begin and end quote } ; -server: - SERVER_WITH_PORT NUMBER +distribution: + CONSISTENT + { + $$= MEMCACHED_DISTRIBUTION_CONSISTENT; + } + | MODULA { - $$.c_str= $1.c_str; - $$.length= $1.length; - $$.port= $2; + $$= MEMCACHED_DISTRIBUTION_MODULA; } - | IDENTIFIER + | RANDOM { - $$.c_str= $1.c_str; - $$.length= $1.length; - $$.port= 80; + $$= MEMCACHED_DISTRIBUTION_RANDOM; } ; + +%% + +void Context::start() +{ + config_parse(this, (void **)scanner); +} +