Update for --socket option
[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="config_"
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/common.h>
43 #include <libmemcached/options.hpp>
44
45 #include <libmemcached/options/context.h>
46 #include <libmemcached/options/symbol.h>
47 #include <libmemcached/options/scanner.h>
48
49 #include <iostream>
50
51 #pragma GCC diagnostic ignored "-Wold-style-cast"
52
53 int conf_lex(YYSTYPE* lvalp, void* scanner);
54
55 #define parser_abort(A, B) do { (A)->abort((B)); YYABORT; } while (0)
56
57 inline void config_error(Context *context, yyscan_t *scanner, const char *error)
58 {
59 if (not context->end())
60 context->abort(error);
61 }
62
63 %}
64
65 %token COMMENT
66 %token END
67 %token ERROR
68 %token RESET
69 %token PARSER_DEBUG
70 %token INCLUDE
71 %token CONFIGURE_FILE
72 %token EMPTY_LINE
73 %token SERVER
74 %token SOCKET
75 %token SERVERS
76 %token SERVERS_OPTION
77 %token UNKNOWN_OPTION
78 %token UNKNOWN
79
80 /* All behavior options */
81 %token BINARY_PROTOCOL
82 %token BUFFER_REQUESTS
83 %token CONNECT_TIMEOUT
84 %token DISTRIBUTION
85 %token HASH
86 %token HASH_WITH_NAMESPACE
87 %token IO_BYTES_WATERMARK
88 %token IO_KEY_PREFETCH
89 %token IO_MSG_WATERMARK
90 %token KETAMA_HASH
91 %token KETAMA_WEIGHTED
92 %token NOREPLY
93 %token NUMBER_OF_REPLICAS
94 %token POLL_TIMEOUT
95 %token RANDOMIZE_REPLICA_READ
96 %token RCV_TIMEOUT
97 %token REMOVE_FAILED_SERVERS
98 %token RETRY_TIMEOUT
99 %token SND_TIMEOUT
100 %token SOCKET_RECV_SIZE
101 %token SOCKET_SEND_SIZE
102 %token SORT_HOSTS
103 %token SUPPORT_CAS
104 %token USER_DATA
105 %token USE_UDP
106 %token VERIFY_KEY
107 %token _TCP_KEEPALIVE
108 %token _TCP_KEEPIDLE
109 %token _TCP_NODELAY
110
111 /* Callbacks */
112 %token NAMESPACE
113
114 /* Pool */
115 %token POOL_MIN
116 %token POOL_MAX
117
118 /* Hash types */
119 %token MD5
120 %token CRC
121 %token FNV1_64
122 %token FNV1A_64
123 %token FNV1_32
124 %token FNV1A_32
125 %token HSIEH
126 %token MURMUR
127 %token JENKINS
128
129 /* Distributions */
130 %token CONSISTENT
131 %token MODULA
132 %token RANDOM
133
134 /* Boolean values */
135 %token <boolean> TRUE
136 %token <boolean> FALSE
137
138 %nonassoc ','
139 %nonassoc '='
140
141 %token <number> FLOAT
142 %token <number> NUMBER
143 %token <number> PORT
144 %token <number> WEIGHT_START
145 %token <server> IPADDRESS
146 %token <server> HOSTNAME
147 %token <string> STRING
148 %token <string> QUOTED_STRING
149 %token <string> FILE_PATH
150
151 %type <behavior> behavior_boolean
152 %type <behavior> behavior_number
153 %type <distribution> distribution
154 %type <hash> hash
155 %type <number> optional_port
156 %type <number> optional_weight
157 %type <string> string
158
159 %%
160
161 begin:
162 statement
163 | begin ' ' statement
164 ;
165
166 statement:
167 expression
168 { }
169 | COMMENT
170 { }
171 | EMPTY_LINE
172 { }
173 | END
174 {
175 context->set_end();
176 YYACCEPT;
177 }
178 | ERROR
179 {
180 context->rc= MEMCACHED_PARSE_USER_ERROR;
181 parser_abort(context, NULL);
182 }
183 | RESET
184 {
185 memcached_reset(context->memc);
186 }
187 | PARSER_DEBUG
188 {
189 yydebug= 1;
190 }
191 | INCLUDE ' ' string
192 {
193 if ((context->rc= memcached_parse_configure_file(*context->memc, $3.c_str, $3.size)) != MEMCACHED_SUCCESS)
194 {
195 parser_abort(context, NULL);
196 }
197 }
198 ;
199
200
201 expression:
202 SERVER HOSTNAME optional_port optional_weight
203 {
204 if (memcached_failed(context->rc= memcached_server_add_with_weight(context->memc, $2.c_str, $3, $4)))
205 {
206 parser_abort(context, NULL);
207 }
208 context->unset_server();
209 }
210 | SERVER IPADDRESS optional_port optional_weight
211 {
212 if (memcached_failed(context->rc= memcached_server_add_with_weight(context->memc, $2.c_str, $3, $4)))
213 {
214 parser_abort(context, NULL);
215 }
216 context->unset_server();
217 }
218 | SOCKET string
219 {
220 if (memcached_failed(context->rc= memcached_server_add_unix_socket(context->memc, $2.c_str)))
221 {
222 parser_abort(context, NULL);
223 }
224 }
225 | CONFIGURE_FILE string
226 {
227 memcached_set_configuration_file(context->memc, $2.c_str, $2.size);
228 }
229 | POOL_MIN NUMBER
230 {
231 context->memc->configure.initial_pool_size= $2;
232 }
233 | POOL_MAX NUMBER
234 {
235 context->memc->configure.max_pool_size= $2;
236 }
237 | behaviors
238 ;
239
240 behaviors:
241 NAMESPACE string
242 {
243 if ((context->rc= memcached_set_namespace(context->memc, $2.c_str, $2.size)) != MEMCACHED_SUCCESS)
244 {
245 parser_abort(context, NULL);;
246 }
247 }
248 | DISTRIBUTION distribution
249 {
250 if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $2)) != MEMCACHED_SUCCESS)
251 {
252 parser_abort(context, NULL);;
253 }
254 }
255 | DISTRIBUTION distribution ',' hash
256 {
257 if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $2)) != MEMCACHED_SUCCESS)
258 {
259 parser_abort(context, NULL);;
260 }
261 if ((context->rc= memcached_behavior_set_distribution_hash(context->memc, $4)) != MEMCACHED_SUCCESS)
262 {
263 parser_abort(context, NULL);;
264 }
265 }
266 | HASH hash
267 {
268 if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_HASH, $2)) != MEMCACHED_SUCCESS)
269 {
270 parser_abort(context, NULL);;
271 }
272 }
273 | behavior_number NUMBER
274 {
275 if ((context->rc= memcached_behavior_set(context->memc, $1, $2)) != MEMCACHED_SUCCESS)
276 {
277 parser_abort(context, NULL);;
278 }
279 }
280 | behavior_boolean
281 {
282 if ((context->rc= memcached_behavior_set(context->memc, $1, true)) != MEMCACHED_SUCCESS)
283 {
284 parser_abort(context, NULL);;
285 }
286 }
287 | USER_DATA
288 {
289 }
290 ;
291
292 behavior_number:
293 REMOVE_FAILED_SERVERS
294 {
295 $$= MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS;
296 }
297 | CONNECT_TIMEOUT
298 {
299 $$= MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT;
300 }
301 | IO_MSG_WATERMARK
302 {
303 $$= MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK;
304 }
305 | IO_BYTES_WATERMARK
306 {
307 $$= MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK;
308 }
309 | IO_KEY_PREFETCH
310 {
311 $$= MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH;
312 }
313 | NUMBER_OF_REPLICAS
314 {
315 $$= MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS;
316 }
317 | POLL_TIMEOUT
318 {
319 $$= MEMCACHED_BEHAVIOR_POLL_TIMEOUT;
320 }
321 | RCV_TIMEOUT
322 {
323 $$= MEMCACHED_BEHAVIOR_RCV_TIMEOUT;
324 }
325 | RETRY_TIMEOUT
326 {
327 $$= MEMCACHED_BEHAVIOR_RETRY_TIMEOUT;
328 }
329 | SND_TIMEOUT
330 {
331 $$= MEMCACHED_BEHAVIOR_SND_TIMEOUT;
332 }
333 | SOCKET_RECV_SIZE
334 {
335 $$= MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE;
336 }
337 | SOCKET_SEND_SIZE
338 {
339 $$= MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE;
340 }
341 ;
342
343 behavior_boolean:
344 BINARY_PROTOCOL
345 {
346 $$= MEMCACHED_BEHAVIOR_BINARY_PROTOCOL;
347 }
348 | BUFFER_REQUESTS
349 {
350 $$= MEMCACHED_BEHAVIOR_BUFFER_REQUESTS;
351 }
352 | HASH_WITH_NAMESPACE
353 {
354 $$= MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY;
355 }
356 | NOREPLY
357 {
358 $$= MEMCACHED_BEHAVIOR_NOREPLY;
359 }
360 | RANDOMIZE_REPLICA_READ
361 {
362 $$= MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ;
363 }
364 | SORT_HOSTS
365 {
366 $$= MEMCACHED_BEHAVIOR_SORT_HOSTS;
367 }
368 | SUPPORT_CAS
369 {
370 $$= MEMCACHED_BEHAVIOR_SUPPORT_CAS;
371 }
372 | _TCP_NODELAY
373 {
374 $$= MEMCACHED_BEHAVIOR_TCP_NODELAY;
375 }
376 | _TCP_KEEPALIVE
377 {
378 $$= MEMCACHED_BEHAVIOR_TCP_KEEPALIVE;
379 }
380 | _TCP_KEEPIDLE
381 {
382 $$= MEMCACHED_BEHAVIOR_TCP_KEEPIDLE;
383 }
384 | USE_UDP
385 {
386 $$= MEMCACHED_BEHAVIOR_USE_UDP;
387 }
388 | VERIFY_KEY
389 {
390 $$= MEMCACHED_BEHAVIOR_VERIFY_KEY;
391 }
392
393
394 optional_port:
395 { $$= MEMCACHED_DEFAULT_PORT;}
396 | PORT
397 { };
398 ;
399
400 optional_weight:
401 { $$= 1; }
402 | WEIGHT_START
403 { }
404 ;
405
406 hash:
407 MD5
408 {
409 $$= MEMCACHED_HASH_MD5;
410 }
411 | CRC
412 {
413 $$= MEMCACHED_HASH_CRC;
414 }
415 | FNV1_64
416 {
417 $$= MEMCACHED_HASH_FNV1_64;
418 }
419 | FNV1A_64
420 {
421 $$= MEMCACHED_HASH_FNV1A_64;
422 }
423 | FNV1_32
424 {
425 $$= MEMCACHED_HASH_FNV1_32;
426 }
427 | FNV1A_32
428 {
429 $$= MEMCACHED_HASH_FNV1A_32;
430 }
431 | HSIEH
432 {
433 $$= MEMCACHED_HASH_HSIEH;
434 }
435 | MURMUR
436 {
437 $$= MEMCACHED_HASH_MURMUR;
438 }
439 | JENKINS
440 {
441 $$= MEMCACHED_HASH_JENKINS;
442 }
443 ;
444
445 string:
446 STRING
447 {
448 $$= $1;
449 }
450 | QUOTED_STRING
451 {
452 $$.c_str= $1.c_str +1; // +1 to move use passed the initial quote
453 $$.size= $1.size -2; // -2 removes the begin and end quote
454 }
455 ;
456
457 distribution:
458 CONSISTENT
459 {
460 $$= MEMCACHED_DISTRIBUTION_CONSISTENT;
461 }
462 | MODULA
463 {
464 $$= MEMCACHED_DISTRIBUTION_MODULA;
465 }
466 | RANDOM
467 {
468 $$= MEMCACHED_DISTRIBUTION_RANDOM;
469 }
470 ;
471
472 %%
473
474 void Context::start()
475 {
476 config_parse(this, (void **)scanner);
477 }
478