81f140a4e3c24fabbaec17f48d8f2f6c66bff707
[alexxy/gromacs.git] / src / gromacs / selection / parser.y
1 %code requires {
2 /*
3  * This file is part of the GROMACS molecular simulation package.
4  *
5  * Copyright (c) 2009,2010,2011,2012, by the GROMACS development team, led by
6  * David van der Spoel, Berk Hess, Erik Lindahl, and including many
7  * others, as listed in the AUTHORS file in the top-level source
8  * directory and at http://www.gromacs.org.
9  *
10  * GROMACS is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public License
12  * as published by the Free Software Foundation; either version 2.1
13  * of the License, or (at your option) any later version.
14  *
15  * GROMACS is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with GROMACS; if not, see
22  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
24  *
25  * If you want to redistribute modifications to GROMACS, please
26  * consider that scientific software is very special. Version
27  * control is crucial - bugs must be traceable. We will be happy to
28  * consider code for inclusion in the official distribution, but
29  * derived work must not be called official GROMACS. Details are found
30  * in the README & COPYING files - if they are missing, get the
31  * official version at http://www.gromacs.org.
32  *
33  * To help us fund GROMACS development, we humbly ask that you cite
34  * the research papers on the package. Check out http://www.gromacs.org.
35  */
36 }
37 /*! \internal \file
38  * \brief Grammar description and parser for the selection language.
39  *
40  * \author Teemu Murtola <teemu.murtola@gmail.com>
41  * \ingroup module_selection
42  */
43 %{
44 /*! \internal \file parser.cpp
45  * \brief Generated (from parser.y by Bison) parser for the selection language.
46  *
47  * \ingroup module_selection
48  */
49 /*! \internal \file parser.h
50  * \brief Generated (from parser.y by Bison) parser include file.
51  *
52  * \ingroup module_selection
53  */
54 #include "gromacs/legacyheaders/smalloc.h"
55
56 #include "parser_internal.h"
57
58 using gmx::scoped_ptr_sfree;
59 using gmx::SelectionParserValue;
60 using gmx::SelectionParserValueList;
61 using gmx::SelectionParserValueListPointer;
62 using gmx::SelectionParserParameter;
63 using gmx::SelectionParserParameterList;
64 using gmx::SelectionParserParameterListPointer;
65 using gmx::SelectionTreeElement;
66 using gmx::SelectionTreeElementPointer;
67
68 #ifdef _MSC_VER
69 #pragma warning(disable: 4065)
70 #endif
71 %}
72
73 %code requires{
74 #include "parsetree.h"
75 #include "selelem.h"
76 }
77
78 %union{
79     int                         i;
80     real                        r;
81     char                       *str;
82     struct gmx_ana_selmethod_t *meth;
83
84     gmx::SelectionStringMatchType                smt;
85
86     gmx::SelectionTreeElementPointer            *sel;
87     gmx::SelectionParserValue                   *val;
88     gmx::SelectionParserValueListPointer        *vlist;
89     gmx::SelectionParserParameter               *param;
90     gmx::SelectionParserParameterListPointer    *plist;
91 };
92
93 /* Invalid token to report lexer errors */
94 %token INVALID
95
96 /* Tokens for help requests */
97 %token         HELP
98 %token <str>   HELP_TOPIC
99
100 /* Simple input tokens */
101 %token <i>     TOK_INT
102 %token <r>     TOK_REAL
103 %token <str>   STR
104 %token <str>   IDENTIFIER
105 %token         CMD_SEP
106
107 /* Simple keyword tokens */
108 %token         GROUP
109 %token         TO
110
111 /* Variable tokens */
112 %token <sel>   VARIABLE_NUMERIC
113 %token <sel>   VARIABLE_GROUP
114 %token <sel>   VARIABLE_POS
115
116 /* Selection method tokens */
117 %token <meth>  KEYWORD_NUMERIC
118 %token <meth>  KEYWORD_STR
119 %token <str>   KEYWORD_POS
120 %token <meth>  KEYWORD_GROUP
121 %token <meth>  METHOD_NUMERIC
122 %token <meth>  METHOD_GROUP
123 %token <meth>  METHOD_POS
124 %token <meth>  MODIFIER
125 /* Empty token that should precede any non-position KEYWORD/METHOD token that
126  * is not preceded by KEYWORD_POS. This is used to work around reduce/reduce
127  * conflicts that appear when a lookahead token would require a reduction of
128  * a rule with empty RHS before shifting, and there is an alternative reduction
129  * available. Replacing the empty RHS with a dummy token makes these conflicts
130  * only shift/reduce conflicts. Another alternative would be to remove the
131  * pos_mod non-terminal completely and split each rule that uses it into two,
132  * but this would require duplicating six rules in the grammar. */
133 %token         EMPTY_POSMOD
134
135 %token <str>   PARAM
136 %token         END_OF_METHOD
137
138 %token          OF
139 /* Comparison operators have lower precedence than parameter reduction
140  * to make it possible to parse, e.g., "mindist from resnr 1 < 2" without
141  * parenthesis. */
142 %nonassoc <str> CMP_OP
143 /* A dummy token that determines the precedence of parameter reduction */
144 %nonassoc       PARAM_REDUCT
145 /* Boolean operator tokens */
146 %left           OR XOR
147 %left           AND
148 %left           NOT
149 /* Arithmetic operator tokens */
150 %left           '+' '-'
151 %left           '*' '/'
152 %right          UNARY_NEG   /* Dummy token for unary negation precedence */
153 %right          '^'
154 %nonassoc       NUM_REDUCT  /* Dummy token for numerical keyword reduction precedence */
155
156 /* Simple non-terminals */
157 %type <i>     integer_number
158 %type <r>     real_number number
159 %type <str>   string
160 %type <str>   pos_mod
161 %type <smt>   str_match_type
162
163 /* Expression non-terminals */
164 %type <sel>   commands command cmd_plain
165 %type <sel>   selection
166 %type <sel>   sel_expr
167 %type <sel>   num_expr
168 %type <sel>   str_expr
169 %type <sel>   pos_expr
170
171 /* Parameter/value non-terminals */
172 %type <plist> method_params method_param_list
173 %type <param> method_param
174 %type <vlist> value_list value_list_contents basic_value_list basic_value_list_contents
175 %type <val>   value_item value_item_range basic_value_item
176 %type <vlist> help_topic
177
178 %destructor { free($$);        } HELP_TOPIC STR IDENTIFIER KEYWORD_POS CMP_OP string
179 %destructor { if($$) free($$); } PARAM pos_mod
180 %destructor { delete $$;       } commands command cmd_plain selection
181 %destructor { delete $$;       } sel_expr num_expr str_expr pos_expr
182 %destructor { delete $$;       } method_params method_param_list method_param
183 %destructor { delete $$;       } value_list value_list_contents basic_value_list basic_value_list_contents
184 %destructor { delete $$;       } value_item value_item_range basic_value_item
185 %destructor { delete $$;       } help_topic
186
187 %expect 35
188 %debug
189 %pure-parser
190 %define api.push-pull push
191
192 %name-prefix="_gmx_sel_yy"
193 %parse-param { void *scanner }
194
195 %%
196
197 /* The start rule: allow one or more commands */
198 commands:    /* empty */
199              {
200                  BEGIN_ACTION;
201                  set_empty($$);
202                  END_ACTION;
203              }
204            | commands command
205              {
206                  BEGIN_ACTION;
207                  set($$, _gmx_sel_append_selection(get($2), get($1), scanner));
208                  if (_gmx_sel_parser_should_finish(scanner))
209                      YYACCEPT;
210                  END_ACTION;
211              }
212 ;
213
214 /* A command is formed from an actual command and a separator */
215 command:     cmd_plain CMD_SEP  { $$ = $1; }
216            | error CMD_SEP
217              {
218                  BEGIN_ACTION;
219                  _gmx_selparser_error(scanner, "invalid selection '%s'",
220                                       _gmx_sel_lexer_pselstr(scanner));
221                  _gmx_sel_lexer_clear_method_stack(scanner);
222                  if (_gmx_sel_is_lexer_interactive(scanner))
223                  {
224                      _gmx_sel_lexer_clear_pselstr(scanner);
225                      yyerrok;
226                  }
227                  else
228                  {
229                      YYABORT;
230                  }
231                  set_empty($$);
232                  END_ACTION;
233              }
234 ;
235
236 /* Commands can be selections or variable assignments */
237 cmd_plain:   /* empty */
238              {
239                  BEGIN_ACTION;
240                  _gmx_sel_handle_empty_cmd(scanner);
241                  set_empty($$);
242                  END_ACTION;
243              }
244            | help_request
245              {
246                  BEGIN_ACTION;
247                  set_empty($$);
248                  END_ACTION;
249              }
250            | TOK_INT
251              {
252                  BEGIN_ACTION;
253                  SelectionTreeElementPointer s
254                         = _gmx_sel_init_group_by_id($1, scanner);
255                  SelectionTreeElementPointer p
256                         = _gmx_sel_init_position(s, NULL, scanner);
257                  if (!p) YYERROR;
258                  set($$, _gmx_sel_init_selection(NULL, p, scanner));
259                  END_ACTION;
260              }
261            | string
262              {
263                  BEGIN_ACTION;
264                  scoped_ptr_sfree nameGuard($1);
265                  SelectionTreeElementPointer s
266                         = _gmx_sel_init_group_by_name($1, scanner);
267                  SelectionTreeElementPointer p
268                         = _gmx_sel_init_position(s, NULL, scanner);
269                  if (!p) YYERROR;
270                  set($$, _gmx_sel_init_selection(NULL, p, scanner));
271                  END_ACTION;
272              }
273            | selection
274              {
275                  BEGIN_ACTION;
276                  set($$, _gmx_sel_init_selection(NULL, get($1), scanner));
277                  END_ACTION;
278              }
279            | string selection
280              {
281                  BEGIN_ACTION;
282                  scoped_ptr_sfree nameGuard($1);
283                  set($$, _gmx_sel_init_selection($1, get($2), scanner));
284                  END_ACTION;
285              }
286            | IDENTIFIER '=' sel_expr
287              {
288                  BEGIN_ACTION;
289                  scoped_ptr_sfree nameGuard($1);
290                  set($$, _gmx_sel_assign_variable($1, get($3), scanner));
291                  END_ACTION;
292              }
293            | IDENTIFIER '=' num_expr
294              {
295                  BEGIN_ACTION;
296                  scoped_ptr_sfree nameGuard($1);
297                  set($$, _gmx_sel_assign_variable($1, get($3), scanner));
298                  END_ACTION;
299              }
300            | IDENTIFIER '=' pos_expr
301              {
302                  BEGIN_ACTION;
303                  scoped_ptr_sfree nameGuard($1);
304                  set($$, _gmx_sel_assign_variable($1, get($3), scanner));
305                  END_ACTION;
306              }
307 ;
308
309 /* Help requests */
310 help_request:
311              HELP help_topic
312              {
313                  BEGIN_ACTION;
314                  _gmx_sel_handle_help_cmd(get($2), scanner);
315                  END_ACTION;
316              }
317 ;
318
319 help_topic:  /* empty */
320              {
321                  BEGIN_ACTION;
322                  set($$, SelectionParserValue::createList());
323                  END_ACTION;
324              }
325            | help_topic HELP_TOPIC
326              {
327                  BEGIN_ACTION;
328                  SelectionParserValueListPointer list(get($1));
329                  list->push_back(SelectionParserValue::createString($2));
330                  set($$, move(list));
331                  END_ACTION;
332              }
333 ;
334
335 /* Selection is made of an expression and zero or more modifiers */
336 selection:   pos_expr           { $$ = $1; }
337            | sel_expr
338              {
339                  BEGIN_ACTION;
340                  set($$, _gmx_sel_init_position(get($1), NULL, scanner));
341                  CHECK_SEL($$);
342                  END_ACTION;
343              }
344            | '(' selection ')'  { $$ = $2; }
345            | selection MODIFIER method_params
346              {
347                  BEGIN_ACTION;
348                  set($$, _gmx_sel_init_modifier($2, get($3), get($1), scanner));
349                  CHECK_SEL($$);
350                  END_ACTION;
351              }
352 ;
353
354 /********************************************************************
355  * BASIC NON-TERMINAL SYMBOLS
356  ********************************************************************/
357
358 integer_number:
359              TOK_INT            { $$ = $1; }
360            | '-' TOK_INT        { $$ = -$2; }
361 ;
362
363 real_number:
364              TOK_REAL           { $$ = $1; }
365            | '-' TOK_REAL       { $$ = -$2; }
366 ;
367
368 number:      integer_number     { $$ = $1; }
369            | real_number        { $$ = $1; }
370 ;
371
372 string:      STR                { $$ = $1; }
373            | IDENTIFIER         { $$ = $1; }
374 ;
375
376 /********************************************************************
377  * ATOM SELECTION EXPRESSIONS
378  ********************************************************************/
379
380 /* Boolean expressions and grouping */
381 sel_expr:    NOT sel_expr
382              {
383                  BEGIN_ACTION;
384                  SelectionTreeElementPointer arg(get($2));
385                  SelectionTreeElementPointer sel(
386                         new SelectionTreeElement(SEL_BOOLEAN));
387                  sel->u.boolt = BOOL_NOT;
388                  sel->child = arg;
389                  set($$, sel);
390                  END_ACTION;
391              }
392            | sel_expr AND sel_expr
393              {
394                  BEGIN_ACTION;
395                  SelectionTreeElementPointer arg1(get($1)), arg2(get($3));
396                  SelectionTreeElementPointer sel(
397                         new SelectionTreeElement(SEL_BOOLEAN));
398                  sel->u.boolt = BOOL_AND;
399                  sel->child = arg1; sel->child->next = arg2;
400                  set($$, sel);
401                  END_ACTION;
402              }
403            | sel_expr OR  sel_expr
404              {
405                  BEGIN_ACTION;
406                  SelectionTreeElementPointer arg1(get($1)), arg2(get($3));
407                  SelectionTreeElementPointer sel(
408                         new SelectionTreeElement(SEL_BOOLEAN));
409                  sel->u.boolt = BOOL_OR;
410                  sel->child = arg1; sel->child->next = arg2;
411                  set($$, sel);
412                  END_ACTION;
413              }
414            | '(' sel_expr ')'   { $$ = $2; }
415 ;
416
417 /* Numeric comparisons */
418 sel_expr:    num_expr CMP_OP num_expr
419              {
420                  BEGIN_ACTION;
421                  scoped_ptr_sfree opGuard($2);
422                  set($$, _gmx_sel_init_comparison(get($1), get($3), $2, scanner));
423                  CHECK_SEL($$);
424                  END_ACTION;
425              }
426 ;
427
428 /* External groups */
429 sel_expr:    GROUP string
430              {
431                  BEGIN_ACTION;
432                  scoped_ptr_sfree nameGuard($2);
433                  set($$, _gmx_sel_init_group_by_name($2, scanner));
434                  END_ACTION;
435              }
436            | GROUP TOK_INT
437              {
438                  BEGIN_ACTION;
439                  set($$, _gmx_sel_init_group_by_id($2, scanner));
440                  END_ACTION;
441              }
442 ;
443
444 /* Position modifiers for selection methods */
445 pos_mod:     EMPTY_POSMOD       { $$ = NULL; }
446            | KEYWORD_POS        { $$ = $1;   }
447 ;
448
449 /* Matching mode forcing for keyword matching */
450 str_match_type:
451              '~'                { $$ = gmx::eStringMatchType_RegularExpression; }
452            | '?'                { $$ = gmx::eStringMatchType_Wildcard; }
453            | '='                { $$ = gmx::eStringMatchType_Exact; }
454 ;
455
456 /* Keyword selections */
457 sel_expr:    pos_mod KEYWORD_GROUP
458              {
459                  BEGIN_ACTION;
460                  scoped_ptr_sfree posmodGuard($1);
461                  set($$, _gmx_sel_init_keyword($2, SelectionParserValueListPointer(), $1, scanner));
462                  CHECK_SEL($$);
463                  END_ACTION;
464              }
465            | pos_mod KEYWORD_STR basic_value_list
466              {
467                  BEGIN_ACTION;
468                  scoped_ptr_sfree posmodGuard($1);
469                  set($$, _gmx_sel_init_keyword_strmatch($2, gmx::eStringMatchType_Auto, get($3), $1, scanner));
470                  CHECK_SEL($$);
471                  END_ACTION;
472              }
473            | pos_mod KEYWORD_STR str_match_type basic_value_list
474              {
475                  BEGIN_ACTION;
476                  scoped_ptr_sfree posmodGuard($1);
477                  set($$, _gmx_sel_init_keyword_strmatch($2, $3, get($4), $1, scanner));
478                  CHECK_SEL($$);
479                  END_ACTION;
480              }
481            | pos_mod KEYWORD_NUMERIC basic_value_list
482              {
483                  BEGIN_ACTION;
484                  scoped_ptr_sfree posmodGuard($1);
485                  set($$, _gmx_sel_init_keyword($2, get($3), $1, scanner));
486                  CHECK_SEL($$);
487                  END_ACTION;
488              }
489 ;
490
491 /* Custom selection methods */
492 sel_expr:    pos_mod METHOD_GROUP method_params
493              {
494                  BEGIN_ACTION;
495                  scoped_ptr_sfree posmodGuard($1);
496                  set($$, _gmx_sel_init_method($2, get($3), $1, scanner));
497                  CHECK_SEL($$);
498                  END_ACTION;
499              }
500 ;
501
502 /********************************************************************
503  * NUMERICAL EXPRESSIONS
504  ********************************************************************/
505
506 /* Basic numerical values */
507 num_expr:    TOK_INT
508              {
509                  BEGIN_ACTION;
510                  SelectionTreeElementPointer sel(
511                         new SelectionTreeElement(SEL_CONST));
512                  _gmx_selelem_set_vtype(sel, INT_VALUE);
513                  _gmx_selvalue_reserve(&sel->v, 1);
514                  sel->v.u.i[0] = $1;
515                  set($$, sel);
516                  END_ACTION;
517              }
518            | TOK_REAL
519              {
520                  BEGIN_ACTION;
521                  SelectionTreeElementPointer sel(
522                         new SelectionTreeElement(SEL_CONST));
523                  _gmx_selelem_set_vtype(sel, REAL_VALUE);
524                  _gmx_selvalue_reserve(&sel->v, 1);
525                  sel->v.u.r[0] = $1;
526                  set($$, sel);
527                  END_ACTION;
528              }
529 ;
530
531 /* Numeric selection methods */
532 num_expr:    pos_mod KEYWORD_NUMERIC    %prec NUM_REDUCT
533              {
534                  BEGIN_ACTION;
535                  scoped_ptr_sfree posmodGuard($1);
536                  set($$, _gmx_sel_init_keyword($2, SelectionParserValueListPointer(), $1, scanner));
537                  CHECK_SEL($$);
538                  END_ACTION;
539              }
540            | pos_mod METHOD_NUMERIC method_params
541              {
542                  BEGIN_ACTION;
543                  scoped_ptr_sfree posmodGuard($1);
544                  set($$, _gmx_sel_init_method($2, get($3), $1, scanner));
545                  CHECK_SEL($$);
546                  END_ACTION;
547              }
548 ;
549
550 /* Arithmetic evaluation and grouping */
551 num_expr:    num_expr '+' num_expr
552              {
553                  BEGIN_ACTION;
554                  set($$, _gmx_sel_init_arithmetic(get($1), get($3), '+', scanner));
555                  END_ACTION;
556              }
557            | num_expr '-' num_expr
558              {
559                  BEGIN_ACTION;
560                  set($$, _gmx_sel_init_arithmetic(get($1), get($3), '-', scanner));
561                  END_ACTION;
562              }
563            | num_expr '*' num_expr
564              {
565                  BEGIN_ACTION;
566                  set($$, _gmx_sel_init_arithmetic(get($1), get($3), '*', scanner));
567                  END_ACTION;
568              }
569            | num_expr '/' num_expr
570              {
571                  BEGIN_ACTION;
572                  set($$, _gmx_sel_init_arithmetic(get($1), get($3), '/', scanner));
573                  END_ACTION;
574              }
575            | '-' num_expr %prec UNARY_NEG
576              {
577                  BEGIN_ACTION;
578                  set($$, _gmx_sel_init_arithmetic(get($2), SelectionTreeElementPointer(), '-', scanner));
579                  END_ACTION;
580              }
581            | num_expr '^' num_expr
582              {
583                  BEGIN_ACTION;
584                  set($$, _gmx_sel_init_arithmetic(get($1), get($3), '^', scanner));
585                  END_ACTION;
586              }
587            | '(' num_expr ')'   { $$ = $2; }
588 ;
589
590 /********************************************************************
591  * STRING EXPRESSIONS
592  ********************************************************************/
593
594 str_expr:    string
595              {
596                  BEGIN_ACTION;
597                  SelectionTreeElementPointer sel(
598                         new SelectionTreeElement(SEL_CONST));
599                  _gmx_selelem_set_vtype(sel, STR_VALUE);
600                  _gmx_selvalue_reserve(&sel->v, 1);
601                  sel->v.u.s[0] = $1;
602                  set($$, sel);
603                  END_ACTION;
604              }
605            | pos_mod KEYWORD_STR
606              {
607                  BEGIN_ACTION;
608                  scoped_ptr_sfree posmodGuard($1);
609                  set($$, _gmx_sel_init_keyword($2, SelectionParserValueListPointer(), $1, scanner));
610                  CHECK_SEL($$);
611                  END_ACTION;
612              }
613 ;
614
615 /********************************************************************
616  * POSITION EXPRESSIONS
617  ********************************************************************/
618
619 /* Constant position expressions */
620 pos_expr:    '[' number ',' number ',' number ']'
621              {
622                  BEGIN_ACTION;
623                  set($$, _gmx_sel_init_const_position($2, $4, $6));
624                  END_ACTION;
625              }
626 ;
627
628 /* Grouping of position expressions */
629 pos_expr:    '(' pos_expr ')'   { $$ = $2; }
630 ;
631
632 /* Expressions with a position value */
633 pos_expr:    METHOD_POS method_params
634              {
635                  BEGIN_ACTION;
636                  set($$, _gmx_sel_init_method($1, get($2), NULL, scanner));
637                  CHECK_SEL($$);
638                  END_ACTION;
639              }
640 ;
641
642 /* Evaluation of positions using a keyword */
643 pos_expr:    KEYWORD_POS OF sel_expr    %prec PARAM_REDUCT
644              {
645                  BEGIN_ACTION;
646                  scoped_ptr_sfree keywordGuard($1);
647                  set($$, _gmx_sel_init_position(get($3), $1, scanner));
648                  CHECK_SEL($$);
649                  END_ACTION;
650              }
651 ;
652
653 /********************************************************************
654  * VARIABLES
655  ********************************************************************/
656
657 sel_expr:    VARIABLE_GROUP
658              {
659                  BEGIN_ACTION;
660                  set($$, _gmx_sel_init_variable_ref(get($1)));
661                  END_ACTION;
662              }
663 ;
664
665 num_expr:    VARIABLE_NUMERIC
666              {
667                  BEGIN_ACTION;
668                  set($$, _gmx_sel_init_variable_ref(get($1)));
669                  END_ACTION;
670              }
671 ;
672
673 pos_expr:    VARIABLE_POS
674              {
675                  BEGIN_ACTION;
676                  set($$, _gmx_sel_init_variable_ref(get($1)));
677                  END_ACTION;
678              }
679 ;
680
681 /********************************************************************
682  * METHOD PARAMETERS
683  ********************************************************************/
684
685 method_params:
686              method_param_list
687              { $$ = $1; }
688            | method_param_list END_OF_METHOD
689              { $$ = $1; }
690 ;
691
692 method_param_list:
693              /* empty */
694              {
695                  BEGIN_ACTION;
696                  set($$, SelectionParserParameter::createList());
697                  END_ACTION;
698              }
699            | method_param_list method_param
700              {
701                  BEGIN_ACTION;
702                  SelectionParserParameterListPointer list(get($1));
703                  list->push_back(get($2));
704                  set($$, move(list));
705                  END_ACTION;
706              }
707 ;
708
709 method_param:
710              PARAM value_list
711              {
712                  BEGIN_ACTION;
713                  scoped_ptr_sfree nameGuard($1);
714                  set($$, SelectionParserParameter::create($1, get($2)));
715                  END_ACTION;
716              }
717 ;
718
719 value_list:  value_list_contents                 { $$ = $1;   }
720            | '{' value_list_contents '}'         { $$ = $2;   }
721 ;
722
723 value_list_contents:
724              /* empty */
725              {
726                  BEGIN_ACTION;
727                  set($$, SelectionParserValue::createList());
728                  END_ACTION;
729              }
730            | value_list_contents value_item
731              {
732                  BEGIN_ACTION;
733                  SelectionParserValueListPointer list(get($1));
734                  list->push_back(get($2));
735                  set($$, move(list));
736                  END_ACTION;
737              }
738            | value_list_contents ',' value_item
739              {
740                  BEGIN_ACTION;
741                  SelectionParserValueListPointer list(get($1));
742                  list->push_back(get($3));
743                  set($$, move(list));
744                  END_ACTION;
745              }
746 ;
747
748 basic_value_list:
749              basic_value_list_contents           { $$ = $1; }
750            | '{' basic_value_list_contents '}'   { $$ = $2; }
751 ;
752
753 basic_value_list_contents:
754              basic_value_item
755              {
756                  BEGIN_ACTION;
757                  set($$, SelectionParserValue::createList(get($1)));
758                  END_ACTION;
759              }
760            | basic_value_list_contents basic_value_item
761              {
762                  BEGIN_ACTION;
763                  SelectionParserValueListPointer list(get($1));
764                  list->push_back(get($2));
765                  set($$, move(list));
766                  END_ACTION;
767              }
768            | basic_value_list_contents ',' basic_value_item
769              {
770                  BEGIN_ACTION;
771                  SelectionParserValueListPointer list(get($1));
772                  list->push_back(get($3));
773                  set($$, move(list));
774                  END_ACTION;
775              }
776 ;
777
778 value_item:  sel_expr            %prec PARAM_REDUCT
779              {
780                  BEGIN_ACTION;
781                  set($$, SelectionParserValue::createExpr(get($1)));
782                  END_ACTION;
783              }
784            | pos_expr            %prec PARAM_REDUCT
785              {
786                  BEGIN_ACTION;
787                  set($$, SelectionParserValue::createExpr(get($1)));
788                  END_ACTION;
789              }
790            | num_expr            %prec PARAM_REDUCT
791              {
792                  BEGIN_ACTION;
793                  set($$, SelectionParserValue::createExpr(get($1)));
794                  END_ACTION;
795              }
796            | str_expr            %prec PARAM_REDUCT
797              {
798                  BEGIN_ACTION;
799                  set($$, SelectionParserValue::createExpr(get($1)));
800                  END_ACTION;
801              }
802            | value_item_range    { $$ = $1; }
803 ;
804
805 basic_value_item:
806              integer_number      %prec PARAM_REDUCT
807              {
808                  BEGIN_ACTION;
809                  set($$, SelectionParserValue::createInteger($1));
810                  END_ACTION;
811              }
812            | real_number         %prec PARAM_REDUCT
813              {
814                  BEGIN_ACTION;
815                  set($$, SelectionParserValue::createReal($1));
816                  END_ACTION;
817              }
818            | string              %prec PARAM_REDUCT
819              {
820                  BEGIN_ACTION;
821                  scoped_ptr_sfree stringGuard($1);
822                  set($$, SelectionParserValue::createString($1));
823                  END_ACTION;
824              }
825            | value_item_range    { $$ = $1; }
826 ;
827
828 value_item_range:
829              integer_number TO integer_number
830              {
831                  BEGIN_ACTION;
832                  set($$, SelectionParserValue::createIntegerRange($1, $3));
833                  END_ACTION;
834              }
835            | integer_number TO real_number
836              {
837                  BEGIN_ACTION;
838                  set($$, SelectionParserValue::createRealRange($1, $3));
839                  END_ACTION;
840              }
841            | real_number TO number
842              {
843                  BEGIN_ACTION;
844                  set($$, SelectionParserValue::createRealRange($1, $3));
845                  END_ACTION;
846              }
847 ;