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