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