3 * This file is part of the GROMACS molecular simulation package.
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.
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.
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.
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.
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.
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.
38 * \brief Grammar description and parser for the selection language.
40 * \author Teemu Murtola <teemu.murtola@gmail.com>
41 * \ingroup module_selection
44 /*! \internal \file parser.cpp
45 * \brief Generated (from parser.y by Bison) parser for the selection language.
47 * \ingroup module_selection
49 /*! \internal \file parser.h
50 * \brief Generated (from parser.y by Bison) parser include file.
52 * \ingroup module_selection
57 #include "gromacs/utility/unique_cptr.h"
59 #include "parser_internal.h"
61 using gmx
::sfree_guard
;
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
;
72 #pragma warning(disable: 4065)
77 #include "parsetree.h"
80 #define YYLTYPE ::gmx::SelectionLocation
87 struct gmx_ana_selmethod_t
*meth
;
89 gmx
::SelectionStringMatchType smt
;
91 gmx
::SelectionTreeElementPointer
*sel
;
92 gmx
::SelectionParserValue
*val
;
93 gmx
::SelectionParserValueListPointer
*vlist
;
94 gmx
::SelectionParserParameter
*param
;
95 gmx
::SelectionParserParameterListPointer
*plist
;
98 /* Invalid token to report lexer errors */
101 /* Simple input tokens */
105 %token
<str
> IDENTIFIER
108 /* Simple keyword tokens */
112 /* Variable tokens */
113 %token
<sel
> VARIABLE_NUMERIC
114 %token
<sel
> VARIABLE_GROUP
115 %token
<sel
> VARIABLE_POS
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. */
140 /* Comparison operators have lower precedence than parameter reduction
141 * to make it possible to parse, e.g., "mindist from resnr 1 < 2" without
143 %nonassoc
<str
> CMP_OP
144 /* A dummy token that determines the precedence of parameter reduction */
145 %nonassoc PARAM_REDUCT
146 /* Boolean operator tokens */
150 /* Arithmetic operator tokens */
153 %right UNARY_NEG
/* Dummy token for unary negation precedence */
155 %nonassoc NUM_REDUCT
/* Dummy token for numerical keyword reduction precedence */
157 /* Simple non-terminals */
158 %type
<i
> integer_number
159 %type
<r
> real_number number
162 %type
<smt
> str_match_type
164 /* Expression non-terminals */
165 %type
<sel
> commands command cmd_plain
166 %type
<sel
> selection
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
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
189 %define api.push
-pull push
192 %name
-prefix
"_gmx_sel_yy"
193 %parse
-param
{ void *scanner
}
197 /* The start rule: allow one or more commands */
198 commands: /* empty */
207 set
($$
, _gmx_sel_append_selection
(get
($2), get
($1), scanner
));
208 if
(_gmx_sel_parser_should_finish
(scanner
)) {
216 /* A command is formed from an actual command and a separator */
217 command: cmd_plain CMD_SEP
{ $$
= $1; }
221 _gmx_sel_lexer_clear_method_stack
(scanner
);
222 if
(_gmx_selparser_handle_error
(scanner
))
230 _gmx_sel_lexer_clear_pselstr
(scanner
);
236 /* Commands can be selections or variable assignments */
237 cmd_plain: /* empty */
246 SelectionTreeElementPointer s
247 = _gmx_sel_init_group_by_id
($1, scanner
);
248 SelectionTreeElementPointer p
249 = _gmx_sel_init_position
(s
, NULL
, scanner
);
251 set
($$
, _gmx_sel_init_selection
(NULL
, p
, scanner
));
257 const sfree_guard 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
);
263 set
($$
, _gmx_sel_init_selection
(NULL
, p
, scanner
));
269 set
($$
, _gmx_sel_init_selection
(NULL
, get
($1), scanner
));
275 const sfree_guard nameGuard
($1);
276 set
($$
, _gmx_sel_init_selection
($1, get
($2), scanner
));
279 | IDENTIFIER
'=' sel_expr
282 const sfree_guard nameGuard
($1);
283 set
($$
, _gmx_sel_assign_variable
($1, get
($3), scanner
));
286 | IDENTIFIER
'=' num_expr
289 const sfree_guard nameGuard
($1);
290 set
($$
, _gmx_sel_assign_variable
($1, get
($3), scanner
));
293 | IDENTIFIER
'=' pos_expr
296 const sfree_guard nameGuard
($1);
297 set
($$
, _gmx_sel_assign_variable
($1, get
($3), scanner
));
302 /* Selection is made of an expression and zero or more modifiers */
303 selection: pos_expr
{ $$
= $1; }
307 set
($$
, _gmx_sel_init_position
(get
($1), NULL
, scanner
));
311 |
'(' selection
')' { $$
= $2; }
312 | selection MODIFIER method_params
315 set
($$
, _gmx_sel_init_modifier
($2, get
($3), get
($1), scanner
));
321 /********************************************************************
322 * BASIC NON-TERMINAL SYMBOLS
323 ********************************************************************/
327 |
'-' TOK_INT
{ $$
= -$2; }
331 TOK_REAL
{ $$
= $1; }
332 |
'-' TOK_REAL
{ $$
= -$2; }
335 number: integer_number
{ $$
= $1; }
336 | real_number
{ $$
= $1; }
339 string: STR
{ $$
= $1; }
340 | IDENTIFIER
{ $$
= $1; }
343 /********************************************************************
344 * ATOM SELECTION EXPRESSIONS
345 ********************************************************************/
347 /* Boolean expressions and grouping */
348 sel_expr: NOT sel_expr
351 SelectionTreeElementPointer arg
(get
($2));
352 SelectionTreeElementPointer sel
(
353 new SelectionTreeElement
(SEL_BOOLEAN
, @$
));
354 sel
->u.boolt
= BOOL_NOT
;
359 | sel_expr AND sel_expr
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
;
370 | sel_expr OR sel_expr
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
;
381 |
'(' sel_expr
')' { $$
= $2; }
384 /* Numeric comparisons */
385 sel_expr: num_expr CMP_OP num_expr
388 const sfree_guard opGuard
($2);
389 set
($$
, _gmx_sel_init_comparison
(get
($1), get
($3), $2, scanner
));
395 /* External groups */
396 sel_expr: GROUP
string
399 const sfree_guard nameGuard
($2);
400 set
($$
, _gmx_sel_init_group_by_name
($2, scanner
));
406 set
($$
, _gmx_sel_init_group_by_id
($2, scanner
));
411 /* Position modifiers for selection methods */
412 pos_mod: EMPTY_POSMOD
{ $$
= NULL
; }
413 | KEYWORD_POS
{ $$
= $1; }
416 /* Matching mode forcing for keyword matching */
418 '~' { $$
= gmx
::eStringMatchType_RegularExpression
; }
419 |
'?' { $$
= gmx
::eStringMatchType_Wildcard
; }
420 |
'=' { $$
= gmx
::eStringMatchType_Exact
; }
423 /* Keyword selections */
424 sel_expr: pos_mod KEYWORD_GROUP
427 const sfree_guard posmodGuard
($1);
428 set
($$
, _gmx_sel_init_keyword
($2, SelectionParserValueListPointer
(), $1, scanner
));
432 | pos_mod KEYWORD_STR basic_value_list
435 const sfree_guard posmodGuard
($1);
436 set
($$
, _gmx_sel_init_keyword_strmatch
($2, gmx
::eStringMatchType_Auto
, get
($3), $1, scanner
));
440 | pos_mod KEYWORD_STR str_match_type basic_value_list
443 const sfree_guard posmodGuard
($1);
444 set
($$
, _gmx_sel_init_keyword_strmatch
($2, $3, get
($4), $1, scanner
));
448 | pos_mod KEYWORD_NUMERIC basic_value_list
451 const sfree_guard posmodGuard
($1);
452 set
($$
, _gmx_sel_init_keyword
($2, get
($3), $1, scanner
));
458 /* Custom selection methods */
459 sel_expr: pos_mod METHOD_GROUP method_params
462 const sfree_guard posmodGuard
($1);
463 set
($$
, _gmx_sel_init_method
($2, get
($3), $1, scanner
));
469 /********************************************************************
470 * NUMERICAL EXPRESSIONS
471 ********************************************************************/
473 /* Basic numerical values */
477 SelectionTreeElementPointer sel
(
478 new SelectionTreeElement
(SEL_CONST
, @$
));
479 _gmx_selelem_set_vtype
(sel
, INT_VALUE
);
480 _gmx_selvalue_reserve
(&sel
->v
, 1);
488 SelectionTreeElementPointer sel
(
489 new SelectionTreeElement
(SEL_CONST
, @$
));
490 _gmx_selelem_set_vtype
(sel
, REAL_VALUE
);
491 _gmx_selvalue_reserve
(&sel
->v
, 1);
498 /* Numeric selection methods */
499 num_expr: pos_mod KEYWORD_NUMERIC %prec NUM_REDUCT
502 const sfree_guard posmodGuard
($1);
503 set
($$
, _gmx_sel_init_keyword
($2, SelectionParserValueListPointer
(), $1, scanner
));
507 | pos_mod KEYWORD_NUMERIC OF pos_expr
510 const sfree_guard posmodGuard
($1);
511 set
($$
, _gmx_sel_init_keyword_of
($2, get
($4), $1, scanner
));
515 | pos_mod METHOD_NUMERIC method_params
518 const sfree_guard posmodGuard
($1);
519 set
($$
, _gmx_sel_init_method
($2, get
($3), $1, scanner
));
525 /* Arithmetic evaluation and grouping */
526 num_expr: num_expr
'+' num_expr
529 set
($$
, _gmx_sel_init_arithmetic
(get
($1), get
($3), '+', scanner
));
532 | num_expr
'-' num_expr
535 set
($$
, _gmx_sel_init_arithmetic
(get
($1), get
($3), '-', scanner
));
538 | num_expr
'*' num_expr
541 set
($$
, _gmx_sel_init_arithmetic
(get
($1), get
($3), '*', scanner
));
544 | num_expr
'/' num_expr
547 set
($$
, _gmx_sel_init_arithmetic
(get
($1), get
($3), '/', scanner
));
550 |
'-' num_expr %prec UNARY_NEG
553 set
($$
, _gmx_sel_init_arithmetic
(get
($2), SelectionTreeElementPointer
(), '-', scanner
));
556 | num_expr
'^' num_expr
559 set
($$
, _gmx_sel_init_arithmetic
(get
($1), get
($3), '^', scanner
));
562 |
'(' num_expr
')' { $$
= $2; }
565 /********************************************************************
567 ********************************************************************/
572 SelectionTreeElementPointer sel
(
573 new SelectionTreeElement
(SEL_CONST
, @$
));
574 _gmx_selelem_set_vtype
(sel
, STR_VALUE
);
575 _gmx_selvalue_reserve
(&sel
->v
, 1);
580 | pos_mod KEYWORD_STR
583 const sfree_guard posmodGuard
($1);
584 set
($$
, _gmx_sel_init_keyword
($2, SelectionParserValueListPointer
(), $1, scanner
));
590 /********************************************************************
591 * POSITION EXPRESSIONS
592 ********************************************************************/
594 /* Constant position expressions */
595 pos_expr: '[' number
',' number
',' number
']'
598 set
($$
, _gmx_sel_init_const_position
($2, $4, $6, scanner
));
603 /* Grouping of position expressions */
604 pos_expr: '(' pos_expr
')' { $$
= $2; }
607 /* Expressions with a position value */
608 pos_expr: METHOD_POS method_params
611 set
($$
, _gmx_sel_init_method
($1, get
($2), NULL
, scanner
));
617 /* Evaluation of positions using a keyword */
618 pos_expr: KEYWORD_POS OF sel_expr %prec PARAM_REDUCT
621 const sfree_guard keywordGuard
($1);
622 set
($$
, _gmx_sel_init_position
(get
($3), $1, scanner
));
628 /********************************************************************
630 ********************************************************************/
632 sel_expr: VARIABLE_GROUP
635 set
($$
, _gmx_sel_init_variable_ref
(get
($1), scanner
));
640 num_expr: VARIABLE_NUMERIC
643 set
($$
, _gmx_sel_init_variable_ref
(get
($1), scanner
));
648 pos_expr: VARIABLE_POS
651 set
($$
, _gmx_sel_init_variable_ref
(get
($1), scanner
));
656 /********************************************************************
658 ********************************************************************/
663 | method_param_list END_OF_METHOD
671 set
($$
, SelectionParserParameter
::createList
());
674 | method_param_list method_param
677 SelectionParserParameterListPointer list
(get
($1));
678 list
->push_back
(get
($2));
679 set
($$
, std
::move
(list
));
688 const sfree_guard nameGuard
($1);
689 set
($$
, SelectionParserParameter
::create
($1, get
($2), @$
));
694 value_list: value_list_contents
{ $$
= $1; }
695 |
'{' value_list_contents
'}' { $$
= $2; }
702 set
($$
, SelectionParserValue
::createList
());
705 | value_list_contents value_item
708 SelectionParserValueListPointer list
(get
($1));
709 list
->push_back
(get
($2));
710 set
($$
, std
::move
(list
));
713 | value_list_contents
',' value_item
716 SelectionParserValueListPointer list
(get
($1));
717 list
->push_back
(get
($3));
718 set
($$
, std
::move
(list
));
724 basic_value_list_contents
{ $$
= $1; }
725 |
'{' basic_value_list_contents
'}' { $$
= $2; }
728 basic_value_list_contents:
732 set
($$
, SelectionParserValue
::createList
(get
($1)));
735 | basic_value_list_contents basic_value_item
738 SelectionParserValueListPointer list
(get
($1));
739 list
->push_back
(get
($2));
740 set
($$
, std
::move
(list
));
743 | basic_value_list_contents
',' basic_value_item
746 SelectionParserValueListPointer list
(get
($1));
747 list
->push_back
(get
($3));
748 set
($$
, std
::move
(list
));
753 value_item: sel_expr %prec PARAM_REDUCT
756 set
($$
, SelectionParserValue
::createExpr
(get
($1)));
759 | pos_expr %prec PARAM_REDUCT
762 set
($$
, SelectionParserValue
::createExpr
(get
($1)));
765 | num_expr %prec PARAM_REDUCT
768 set
($$
, SelectionParserValue
::createExpr
(get
($1)));
771 | str_expr %prec PARAM_REDUCT
774 set
($$
, SelectionParserValue
::createExpr
(get
($1)));
777 | value_item_range
{ $$
= $1; }
781 integer_number %prec PARAM_REDUCT
784 set
($$
, SelectionParserValue
::createInteger
($1, @$
));
787 | real_number %prec PARAM_REDUCT
790 set
($$
, SelectionParserValue
::createReal
($1, @$
));
793 |
string %prec PARAM_REDUCT
796 const sfree_guard stringGuard
($1);
797 set
($$
, SelectionParserValue
::createString
($1, @$
));
800 | value_item_range
{ $$
= $1; }
804 integer_number TO integer_number
807 set
($$
, SelectionParserValue
::createIntegerRange
($1, $3, @$
));
810 | integer_number TO real_number
813 set
($$
, SelectionParserValue
::createRealRange
($1, $3, @$
));
816 | real_number TO number
819 set
($$
, SelectionParserValue
::createRealRange
($1, $3, @$
));