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