3 * This file is part of the GROMACS molecular simulation package.
5 * Copyright (c) 2009,2010,2011,2012,2013 by the GROMACS development team.
6 * Copyright (c) 2014,2015,2016,2020, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
39 * \brief Grammar description and parser for the selection language.
41 * \author Teemu Murtola <teemu.murtola@gmail.com>
42 * \ingroup module_selection
45 /*! \internal \file parser.cpp
46 * \brief Generated (from parser.y by Bison) parser for the selection language.
48 * \ingroup module_selection
50 /*! \internal \file parser.h
51 * \brief Generated (from parser.y by Bison) parser include file.
53 * \ingroup module_selection
58 #include "gromacs/utility/unique_cptr.h"
60 #include "parser_internal.h"
62 using gmx
::sfree_guard
;
63 using gmx
::SelectionParserValue
;
64 using gmx
::SelectionParserValueList
;
65 using gmx
::SelectionParserValueListPointer
;
66 using gmx
::SelectionParserParameter
;
67 using gmx
::SelectionParserParameterList
;
68 using gmx
::SelectionParserParameterListPointer
;
69 using gmx
::SelectionTreeElement
;
70 using gmx
::SelectionTreeElementPointer
;
73 #pragma warning(disable: 4065)
78 #include "parsetree.h"
81 #define YYLTYPE ::gmx::SelectionLocation
88 struct gmx_ana_selmethod_t
*meth
;
90 gmx
::SelectionStringMatchType smt
;
92 gmx
::SelectionTreeElementPointer
*sel
;
93 gmx
::SelectionParserValue
*val
;
94 gmx
::SelectionParserValueListPointer
*vlist
;
95 gmx
::SelectionParserParameter
*param
;
96 gmx
::SelectionParserParameterListPointer
*plist
;
99 /* Invalid token to report lexer errors */
102 /* Simple input tokens */
106 %token
<str
> IDENTIFIER
109 /* Simple keyword tokens */
113 /* Variable tokens */
114 %token
<sel
> VARIABLE_NUMERIC
115 %token
<sel
> VARIABLE_GROUP
116 %token
<sel
> VARIABLE_POS
118 /* Selection method tokens */
119 %token
<meth
> KEYWORD_NUMERIC
120 %token
<meth
> KEYWORD_STR
121 %token
<str
> KEYWORD_POS
122 %token
<meth
> KEYWORD_GROUP
123 %token
<meth
> METHOD_NUMERIC
124 %token
<meth
> METHOD_GROUP
125 %token
<meth
> METHOD_POS
126 %token
<meth
> MODIFIER
127 /* Empty token that should precede any non-position KEYWORD/METHOD token that
128 * is not preceded by KEYWORD_POS. This is used to work around reduce/reduce
129 * conflicts that appear when a lookahead token would require a reduction of
130 * a rule with empty RHS before shifting, and there is an alternative reduction
131 * available. Replacing the empty RHS with a dummy token makes these conflicts
132 * only shift/reduce conflicts. Another alternative would be to remove the
133 * pos_mod non-terminal completely and split each rule that uses it into two,
134 * but this would require duplicating six rules in the grammar. */
141 /* Comparison operators have lower precedence than parameter reduction
142 * to make it possible to parse, e.g., "mindist from resnr 1 < 2" without
144 %nonassoc
<str
> CMP_OP
145 /* A dummy token that determines the precedence of parameter reduction */
146 %nonassoc PARAM_REDUCT
147 /* Boolean operator tokens */
151 /* Arithmetic operator tokens */
154 %right UNARY_NEG
/* Dummy token for unary negation precedence */
156 %nonassoc NUM_REDUCT
/* Dummy token for numerical keyword reduction precedence */
158 /* Simple non-terminals */
159 %type
<i
> integer_number
160 %type
<r
> real_number number
163 %type
<smt
> str_match_type
165 /* Expression non-terminals */
166 %type
<sel
> commands command cmd_plain
167 %type
<sel
> selection
173 /* Parameter/value non-terminals */
174 %type
<plist
> method_params method_param_list
175 %type
<param
> method_param
176 %type
<vlist
> value_list value_list_contents basic_value_list basic_value_list_contents
177 %type
<val
> value_item value_item_range basic_value_item
179 %destructor
{ free
($$
); } STR IDENTIFIER KEYWORD_POS CMP_OP
string
180 %destructor
{ if
($$
) free
($$
); } PARAM pos_mod
181 %destructor
{ delete $$
; } commands command cmd_plain selection
182 %destructor
{ delete $$
; } sel_expr num_expr str_expr pos_expr
183 %destructor
{ delete $$
; } method_params method_param_list method_param
184 %destructor
{ delete $$
; } value_list value_list_contents basic_value_list basic_value_list_contents
185 %destructor
{ delete $$
; } value_item value_item_range basic_value_item
190 %define api.push
-pull push
193 %name
-prefix
"_gmx_sel_yy"
194 %parse
-param
{ void *scanner
}
198 /* The start rule: allow one or more commands */
199 commands: /* empty */
208 set
($$
, _gmx_sel_append_selection
(get
($2), get
($1), scanner
));
209 if
(_gmx_sel_parser_should_finish
(scanner
)) {
217 /* A command is formed from an actual command and a separator */
218 command: cmd_plain CMD_SEP
{ $$
= $1; }
222 _gmx_sel_lexer_clear_method_stack
(scanner
);
223 if
(_gmx_selparser_handle_error
(scanner
))
231 _gmx_sel_lexer_clear_pselstr
(scanner
);
237 /* Commands can be selections or variable assignments */
238 cmd_plain: /* empty */
247 SelectionTreeElementPointer s
248 = _gmx_sel_init_group_by_id
($1, scanner
);
249 SelectionTreeElementPointer p
250 = _gmx_sel_init_position
(s
, NULL
, scanner
);
252 set
($$
, _gmx_sel_init_selection
(NULL
, p
, scanner
));
258 const sfree_guard nameGuard
($1);
259 SelectionTreeElementPointer s
260 = _gmx_sel_init_group_by_name
($1, scanner
);
261 SelectionTreeElementPointer p
262 = _gmx_sel_init_position
(s
, NULL
, scanner
);
264 set
($$
, _gmx_sel_init_selection
(NULL
, p
, scanner
));
270 set
($$
, _gmx_sel_init_selection
(NULL
, get
($1), scanner
));
276 const sfree_guard nameGuard
($1);
277 set
($$
, _gmx_sel_init_selection
($1, get
($2), scanner
));
280 | IDENTIFIER
'=' sel_expr
283 const sfree_guard nameGuard
($1);
284 set
($$
, _gmx_sel_assign_variable
($1, get
($3), scanner
));
287 | IDENTIFIER
'=' num_expr
290 const sfree_guard nameGuard
($1);
291 set
($$
, _gmx_sel_assign_variable
($1, get
($3), scanner
));
294 | IDENTIFIER
'=' pos_expr
297 const sfree_guard nameGuard
($1);
298 set
($$
, _gmx_sel_assign_variable
($1, get
($3), scanner
));
303 /* Selection is made of an expression and zero or more modifiers */
304 selection: pos_expr
{ $$
= $1; }
308 set
($$
, _gmx_sel_init_position
(get
($1), NULL
, scanner
));
312 |
'(' selection
')' { $$
= $2; }
313 | selection MODIFIER method_params
316 set
($$
, _gmx_sel_init_modifier
($2, get
($3), get
($1), scanner
));
322 /********************************************************************
323 * BASIC NON-TERMINAL SYMBOLS
324 ********************************************************************/
328 |
'-' TOK_INT
{ $$
= -$2; }
332 TOK_REAL
{ $$
= $1; }
333 |
'-' TOK_REAL
{ $$
= -$2; }
336 number: integer_number
{ $$
= $1; }
337 | real_number
{ $$
= $1; }
340 string: STR
{ $$
= $1; }
341 | IDENTIFIER
{ $$
= $1; }
344 /********************************************************************
345 * ATOM SELECTION EXPRESSIONS
346 ********************************************************************/
348 /* Boolean expressions and grouping */
349 sel_expr: NOT sel_expr
352 SelectionTreeElementPointer arg
(get
($2));
353 SelectionTreeElementPointer sel
(
354 new SelectionTreeElement
(SEL_BOOLEAN
, @$
));
355 sel
->u.boolt
= BOOL_NOT
;
360 | sel_expr AND sel_expr
363 SelectionTreeElementPointer arg1
(get
($1)), arg2
(get
($3));
364 SelectionTreeElementPointer sel
(
365 new SelectionTreeElement
(SEL_BOOLEAN
, @$
));
366 sel
->u.boolt
= BOOL_AND
;
367 sel
->child
= arg1
; sel
->child
->next
= arg2
;
371 | sel_expr OR sel_expr
374 SelectionTreeElementPointer arg1
(get
($1)), arg2
(get
($3));
375 SelectionTreeElementPointer sel
(
376 new SelectionTreeElement
(SEL_BOOLEAN
, @$
));
377 sel
->u.boolt
= BOOL_OR
;
378 sel
->child
= arg1
; sel
->child
->next
= arg2
;
382 |
'(' sel_expr
')' { $$
= $2; }
385 /* Numeric comparisons */
386 sel_expr: num_expr CMP_OP num_expr
389 const sfree_guard opGuard
($2);
390 set
($$
, _gmx_sel_init_comparison
(get
($1), get
($3), $2, scanner
));
396 /* External groups */
397 sel_expr: GROUP
string
400 const sfree_guard nameGuard
($2);
401 set
($$
, _gmx_sel_init_group_by_name
($2, scanner
));
407 set
($$
, _gmx_sel_init_group_by_id
($2, scanner
));
412 /* Position modifiers for selection methods */
413 pos_mod: EMPTY_POSMOD
{ $$
= NULL
; }
414 | KEYWORD_POS
{ $$
= $1; }
417 /* Matching mode forcing for keyword matching */
419 '~' { $$
= gmx
::eStringMatchType_RegularExpression
; }
420 |
'?' { $$
= gmx
::eStringMatchType_Wildcard
; }
421 |
'=' { $$
= gmx
::eStringMatchType_Exact
; }
424 /* Keyword selections */
425 sel_expr: pos_mod KEYWORD_GROUP
428 const sfree_guard posmodGuard
($1);
429 set
($$
, _gmx_sel_init_keyword
($2, SelectionParserValueListPointer
(), $1, scanner
));
433 | pos_mod KEYWORD_STR basic_value_list
436 const sfree_guard posmodGuard
($1);
437 set
($$
, _gmx_sel_init_keyword_strmatch
($2, gmx
::eStringMatchType_Auto
, get
($3), $1, scanner
));
441 | pos_mod KEYWORD_STR str_match_type basic_value_list
444 const sfree_guard posmodGuard
($1);
445 set
($$
, _gmx_sel_init_keyword_strmatch
($2, $3, get
($4), $1, scanner
));
449 | pos_mod KEYWORD_NUMERIC basic_value_list
452 const sfree_guard posmodGuard
($1);
453 set
($$
, _gmx_sel_init_keyword
($2, get
($3), $1, scanner
));
459 /* Custom selection methods */
460 sel_expr: pos_mod METHOD_GROUP method_params
463 const sfree_guard posmodGuard
($1);
464 set
($$
, _gmx_sel_init_method
($2, get
($3), $1, scanner
));
470 /********************************************************************
471 * NUMERICAL EXPRESSIONS
472 ********************************************************************/
474 /* Basic numerical values */
478 SelectionTreeElementPointer sel
(
479 new SelectionTreeElement
(SEL_CONST
, @$
));
480 _gmx_selelem_set_vtype
(sel
, INT_VALUE
);
481 _gmx_selvalue_reserve
(&sel
->v
, 1);
489 SelectionTreeElementPointer sel
(
490 new SelectionTreeElement
(SEL_CONST
, @$
));
491 _gmx_selelem_set_vtype
(sel
, REAL_VALUE
);
492 _gmx_selvalue_reserve
(&sel
->v
, 1);
499 /* Numeric selection methods */
500 num_expr: pos_mod KEYWORD_NUMERIC %prec NUM_REDUCT
503 const sfree_guard posmodGuard
($1);
504 set
($$
, _gmx_sel_init_keyword
($2, SelectionParserValueListPointer
(), $1, scanner
));
508 | pos_mod KEYWORD_NUMERIC OF pos_expr
511 const sfree_guard posmodGuard
($1);
512 set
($$
, _gmx_sel_init_keyword_of
($2, get
($4), $1, scanner
));
516 | pos_mod METHOD_NUMERIC method_params
519 const sfree_guard posmodGuard
($1);
520 set
($$
, _gmx_sel_init_method
($2, get
($3), $1, scanner
));
526 /* Arithmetic evaluation and grouping */
527 num_expr: num_expr
'+' num_expr
530 set
($$
, _gmx_sel_init_arithmetic
(get
($1), get
($3), '+', scanner
));
533 | num_expr
'-' num_expr
536 set
($$
, _gmx_sel_init_arithmetic
(get
($1), get
($3), '-', scanner
));
539 | num_expr
'*' num_expr
542 set
($$
, _gmx_sel_init_arithmetic
(get
($1), get
($3), '*', scanner
));
545 | num_expr
'/' num_expr
548 set
($$
, _gmx_sel_init_arithmetic
(get
($1), get
($3), '/', scanner
));
551 |
'-' num_expr %prec UNARY_NEG
554 set
($$
, _gmx_sel_init_arithmetic
(get
($2), SelectionTreeElementPointer
(), '-', scanner
));
557 | num_expr
'^' num_expr
560 set
($$
, _gmx_sel_init_arithmetic
(get
($1), get
($3), '^', scanner
));
563 |
'(' num_expr
')' { $$
= $2; }
566 /********************************************************************
568 ********************************************************************/
573 SelectionTreeElementPointer sel
(
574 new SelectionTreeElement
(SEL_CONST
, @$
));
575 _gmx_selelem_set_vtype
(sel
, STR_VALUE
);
576 _gmx_selvalue_reserve
(&sel
->v
, 1);
581 | pos_mod KEYWORD_STR
584 const sfree_guard posmodGuard
($1);
585 set
($$
, _gmx_sel_init_keyword
($2, SelectionParserValueListPointer
(), $1, scanner
));
591 /********************************************************************
592 * POSITION EXPRESSIONS
593 ********************************************************************/
595 /* Constant position expressions */
596 pos_expr: '[' number
',' number
',' number
']'
599 set
($$
, _gmx_sel_init_const_position
($2, $4, $6, scanner
));
604 /* Grouping of position expressions */
605 pos_expr: '(' pos_expr
')' { $$
= $2; }
608 /* Expressions with a position value */
609 pos_expr: METHOD_POS method_params
612 set
($$
, _gmx_sel_init_method
($1, get
($2), NULL
, scanner
));
618 /* Evaluation of positions using a keyword */
619 pos_expr: KEYWORD_POS OF sel_expr %prec PARAM_REDUCT
622 const sfree_guard keywordGuard
($1);
623 set
($$
, _gmx_sel_init_position
(get
($3), $1, scanner
));
629 /********************************************************************
631 ********************************************************************/
633 sel_expr: VARIABLE_GROUP
636 set
($$
, _gmx_sel_init_variable_ref
(get
($1), scanner
));
641 num_expr: VARIABLE_NUMERIC
644 set
($$
, _gmx_sel_init_variable_ref
(get
($1), scanner
));
649 pos_expr: VARIABLE_POS
652 set
($$
, _gmx_sel_init_variable_ref
(get
($1), scanner
));
657 /********************************************************************
659 ********************************************************************/
664 | method_param_list END_OF_METHOD
672 set
($$
, SelectionParserParameter
::createList
());
675 | method_param_list method_param
678 SelectionParserParameterListPointer list
(get
($1));
679 list
->push_back
(get
($2));
680 set
($$
, std
::move
(list
));
689 const sfree_guard nameGuard
($1);
690 set
($$
, SelectionParserParameter
::create
($1, get
($2), @$
));
695 value_list: value_list_contents
{ $$
= $1; }
696 |
'{' value_list_contents
'}' { $$
= $2; }
703 set
($$
, SelectionParserValue
::createList
());
706 | value_list_contents value_item
709 SelectionParserValueListPointer list
(get
($1));
710 list
->push_back
(get
($2));
711 set
($$
, std
::move
(list
));
714 | value_list_contents
',' value_item
717 SelectionParserValueListPointer list
(get
($1));
718 list
->push_back
(get
($3));
719 set
($$
, std
::move
(list
));
725 basic_value_list_contents
{ $$
= $1; }
726 |
'{' basic_value_list_contents
'}' { $$
= $2; }
729 basic_value_list_contents:
733 set
($$
, SelectionParserValue
::createList
(get
($1)));
736 | basic_value_list_contents basic_value_item
739 SelectionParserValueListPointer list
(get
($1));
740 list
->push_back
(get
($2));
741 set
($$
, std
::move
(list
));
744 | basic_value_list_contents
',' basic_value_item
747 SelectionParserValueListPointer list
(get
($1));
748 list
->push_back
(get
($3));
749 set
($$
, std
::move
(list
));
754 value_item: sel_expr %prec PARAM_REDUCT
757 set
($$
, SelectionParserValue
::createExpr
(get
($1)));
760 | pos_expr %prec PARAM_REDUCT
763 set
($$
, SelectionParserValue
::createExpr
(get
($1)));
766 | num_expr %prec PARAM_REDUCT
769 set
($$
, SelectionParserValue
::createExpr
(get
($1)));
772 | str_expr %prec PARAM_REDUCT
775 set
($$
, SelectionParserValue
::createExpr
(get
($1)));
778 | value_item_range
{ $$
= $1; }
782 integer_number %prec PARAM_REDUCT
785 set
($$
, SelectionParserValue
::createInteger
($1, @$
));
788 | real_number %prec PARAM_REDUCT
791 set
($$
, SelectionParserValue
::createReal
($1, @$
));
794 |
string %prec PARAM_REDUCT
797 const sfree_guard stringGuard
($1);
798 set
($$
, SelectionParserValue
::createString
($1, @$
));
801 | value_item_range
{ $$
= $1; }
805 integer_number TO integer_number
808 set
($$
, SelectionParserValue
::createIntegerRange
($1, $3, @$
));
811 | integer_number TO real_number
814 set
($$
, SelectionParserValue
::createRealRange
($1, $3, @$
));
817 | real_number TO number
820 set
($$
, SelectionParserValue
::createRealRange
($1, $3, @$
));