X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Foptions%2Fparser.yy;h=bff5b28df69bb7eaea48033927040399f2547b76;hb=aa6d65c93cadc9869623af385919db1394116934;hp=ae7e6d5f38d1971a185ab9bf236bc55151b607d4;hpb=10f3d6bf1bc11c235779ae735f30758cfb035686;p=m6w6%2Flibmemcached diff --git a/libmemcached/options/parser.yy b/libmemcached/options/parser.yy index ae7e6d5f..bff5b28d 100644 --- a/libmemcached/options/parser.yy +++ b/libmemcached/options/parser.yy @@ -1,141 +1,521 @@ /* 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="libmemcached_" +%parse-param { Context *context } +%parse-param { yyscan_t *scanner } +%locations +%pure-parser +%require "2.2" +%start begin +%verbose + %{ +#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 libmemcached_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner); + +#define parser_abort(A, B) do { parser_abort_func((A), (B)); YYABORT; } while (0) + +inline void parser_abort_func(Context *context, const char *error) { - std::cerr << str << std::endl; - return 0; + (void)error; + if (context->rc == MEMCACHED_SUCCESS) + context->rc= MEMCACHED_PARSE_ERROR; + + std::string error_message; + error_message+= context->begin; + error_message+= " ("; + error_message+= memcached_strerror(NULL, context->rc); + error_message+= ")"; + + memcached_set_error_string(context->memc, context->rc, error_message.c_str(), error_message.size()); } +inline void libmemcached_error(YYLTYPE *locp, Context *context, yyscan_t *scanner, const char *error) +{ + if (not context->end()) + parser_abort_func(context, 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 RESET +%token 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 AUTO_EJECT_HOSTS +%token BINARY_PROTOCOL +%token BUFFER_REQUESTS +%token CACHE_LOOKUPS +%token CONNECT_TIMEOUT +%token _CORK +%token DISTRIBUTION +%token HASH +%token HASH_WITH_PREFIX_KEY +%token IO_BYTES_WATERMARK +%token IO_KEY_PREFETCH +%token IO_MSG_WATERMARK +%token KETAMA +%token KETAMA_HASH +%token KETAMA_WEIGHTED +%token NOREPLY +%token NUMBER_OF_REPLICAS +%token POLL_TIMEOUT +%token RANDOMIZE_REPLICA_READ +%token RCV_TIMEOUT +%token RETRY_TIMEOUT +%token SERVER_FAILURE_LIMIT +%token SND_TIMEOUT +%token SOCKET_RECV_SIZE +%token SOCKET_SEND_SIZE +%token SORT_HOSTS +%token SUPPORT_CAS +%token _TCP_NODELAY +%token _TCP_KEEPALIVE +%token _TCP_KEEPIDLE +%token USER_DATA +%token USE_UDP %token VERIFY_KEY -%token COMMA + +/* Callbacks */ +%token PREFIX_KEY + +/* 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 HOSTNAME +%token HOSTNAME_WITH_PORT +%token IPADDRESS +%token IPADDRESS_WITH_PORT +%token STRING +%token QUOTED_STRING %type server +%type string +%type distribution +%type hash +%type behavior_boolean +%type behavior_number %% +begin: + statement + | statement ' ' statement + ; + statement: - expression + expression + { } + | COMMENT { } - | statement expression + | EMPTY_LINE { } + | END + { + context->set_end(); + YYACCEPT; + } + | RESET + { + memcached_reset(context->memc); + } + | RESET SERVERS + { + memcached_servers_reset(context->memc); + } + | DEBUG + { + yydebug= 1; + } + | DEBUG TRUE + { + yydebug= 1; + } + | DEBUG FALSE + { + yydebug= 0; + } + | INCLUDE string + { + if ((context->rc= memcached_parse_configure_file(context->memc, $2.c_str, $2.length)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL); + } + } ; expression: - SERVER EQ server + SERVER '=' server { - (void) memcached_server_add(parser->memc, $3.c_str, $3.port); + if ((context->rc= memcached_server_add_parsed(context->memc, $3.c_str, $3.length, $3.port, 0)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL); + } } - | SERVERS EQ server_list - { } - | TCPNODELAY + | SERVERS_OPTION '=' server_list { - memcached_behavior_set(parser->memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true); } - | VERIFY_KEY + | CONFIGURE_FILE '=' string { - memcached_behavior_set(parser->memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, true); + memcached_set_configuration_file(context->memc, $3.c_str, $3.length); } + | behaviors ; +behaviors: + PREFIX_KEY '=' string + { + if ((context->rc= memcached_callback_set(context->memc, MEMCACHED_CALLBACK_PREFIX_KEY, std::string($3.c_str, $3.length).c_str())) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL);; + } + } + | DISTRIBUTION '=' distribution + { + if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $3)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL);; + } + } + | HASH '=' hash + { + if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_HASH, $3)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL);; + } + } + | KETAMA_HASH '=' hash + { + if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, $3)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL);; + } + } + | behavior_number '=' NUMBER + { + if ((context->rc= memcached_behavior_set(context->memc, $1, $3)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL);; + } + } + | behavior_boolean + { + if ((context->rc= memcached_behavior_set(context->memc, $1, true)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL);; + } + } + | USER_DATA + { + } + ; + +behavior_number: + 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; + } + | SERVER_FAILURE_LIMIT + { + $$= MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT; + } + | SND_TIMEOUT + { + $$= MEMCACHED_BEHAVIOR_SND_TIMEOUT; + } + | SOCKET_RECV_SIZE + { + $$= MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE; + } + | SOCKET_SEND_SIZE + { + $$= MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE; + } + ; + +behavior_boolean: + AUTO_EJECT_HOSTS + { + $$= MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS; + } + | BINARY_PROTOCOL + { + $$= MEMCACHED_BEHAVIOR_BINARY_PROTOCOL; + } + | BUFFER_REQUESTS + { + $$= MEMCACHED_BEHAVIOR_BUFFER_REQUESTS; + } + | CACHE_LOOKUPS + { + $$= MEMCACHED_BEHAVIOR_CACHE_LOOKUPS; + } + | _CORK + { + $$= MEMCACHED_BEHAVIOR_CORK; + } + | HASH_WITH_PREFIX_KEY + { + $$= MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY; + } + | KETAMA + { + $$= MEMCACHED_BEHAVIOR_KETAMA; + } + | KETAMA_WEIGHTED + { + $$= MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED; + } + | 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; + } + + server_list: - server + server { - (void) memcached_server_add(parser->memc, $1.c_str, $1.port); + if ((context->rc= memcached_server_add_parsed(context->memc, $1.c_str, $1.length, $1.port, 0)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL);; + } } - | server_list COMMA server + | server_list ',' server { - (void) memcached_server_add(parser->memc, $3.c_str, $3.port); + if ((context->rc= memcached_server_add_parsed(context->memc, $3.c_str, $3.length, $3.port, 0)) != MEMCACHED_SUCCESS) + { + parser_abort(context, NULL);; + } } ; server: - SERVER_WITH_PORT NUMBER + HOSTNAME_WITH_PORT NUMBER + { + $$.c_str= $1.c_str; + $$.length= $1.length -1; + $$.port= $2; + } + | HOSTNAME + { + $$.c_str= $1.c_str; + $$.length= $1.length; + $$.port= MEMCACHED_DEFAULT_PORT; + } + | STRING /* a match can be against "localhost" which is just a string */ { $$.c_str= $1.c_str; $$.length= $1.length; + $$.port= MEMCACHED_DEFAULT_PORT; + } + | IPADDRESS_WITH_PORT NUMBER + { + $$.c_str= $1.c_str; + $$.length= $1.length -1; $$.port= $2; } - | IDENTIFIER + | IPADDRESS { $$.c_str= $1.c_str; $$.length= $1.length; - $$.port= 80; + $$.port= MEMCACHED_DEFAULT_PORT; + } + ; + +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_HASH_MURMUR; + } + | JENKINS + { + $$= MEMCACHED_HASH_JENKINS; + } + ; + +string: + STRING + { + $$= $1; + } + | QUOTED_STRING + { + $$.c_str= $1.c_str +1; + $$.length= $1.length -2; + } + ; + +distribution: + CONSISTENT + { + $$= MEMCACHED_DISTRIBUTION_CONSISTENT; + } + | MODULA + { + $$= MEMCACHED_DISTRIBUTION_MODULA; + } + | RANDOM + { + $$= MEMCACHED_DISTRIBUTION_RANDOM; } ;