3 * This file is part of the GROMACS molecular simulation package.
5 * Copyright (c) 2009,2010,2011,2012, by the GROMACS development team, led by
6 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
7 * others, as listed in the AUTHORS file in the top-level source
8 * directory and at http://www.gromacs.org.
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
54 #include "gromacs/legacyheaders/smalloc.h"
56 #include "parser_internal.h"
58 using gmx
::scoped_ptr_sfree
;
59 using gmx
::SelectionParserValue
;
60 using gmx
::SelectionParserValueList
;
61 using gmx
::SelectionParserValueListPointer
;
62 using gmx
::SelectionParserParameter
;
63 using gmx
::SelectionParserParameterList
;
64 using gmx
::SelectionParserParameterListPointer
;
65 using gmx
::SelectionTreeElement
;
66 using gmx
::SelectionTreeElementPointer
;
69 #pragma warning(disable: 4065)
74 #include "parsetree.h"
82 struct gmx_ana_selmethod_t
*meth
;
84 gmx
::SelectionStringMatchType smt
;
86 gmx
::SelectionTreeElementPointer
*sel
;
87 gmx
::SelectionParserValue
*val
;
88 gmx
::SelectionParserValueListPointer
*vlist
;
89 gmx
::SelectionParserParameter
*param
;
90 gmx
::SelectionParserParameterListPointer
*plist
;
93 /* Invalid token to report lexer errors */
96 /* Tokens for help requests */
98 %token
<str
> HELP_TOPIC
100 /* Simple input tokens */
104 %token
<str
> IDENTIFIER
107 /* Simple keyword tokens */
111 /* Variable tokens */
112 %token
<sel
> VARIABLE_NUMERIC
113 %token
<sel
> VARIABLE_GROUP
114 %token
<sel
> VARIABLE_POS
116 /* Selection method tokens */
117 %token
<meth
> KEYWORD_NUMERIC
118 %token
<meth
> KEYWORD_STR
119 %token
<str
> KEYWORD_POS
120 %token
<meth
> KEYWORD_GROUP
121 %token
<meth
> METHOD_NUMERIC
122 %token
<meth
> METHOD_GROUP
123 %token
<meth
> METHOD_POS
124 %token
<meth
> MODIFIER
125 /* Empty token that should precede any non-position KEYWORD/METHOD token that
126 * is not preceded by KEYWORD_POS. This is used to work around reduce/reduce
127 * conflicts that appear when a lookahead token would require a reduction of
128 * a rule with empty RHS before shifting, and there is an alternative reduction
129 * available. Replacing the empty RHS with a dummy token makes these conflicts
130 * only shift/reduce conflicts. Another alternative would be to remove the
131 * pos_mod non-terminal completely and split each rule that uses it into two,
132 * but this would require duplicating six rules in the grammar. */
139 /* Comparison operators have lower precedence than parameter reduction
140 * to make it possible to parse, e.g., "mindist from resnr 1 < 2" without
142 %nonassoc
<str
> CMP_OP
143 /* A dummy token that determines the precedence of parameter reduction */
144 %nonassoc PARAM_REDUCT
145 /* Boolean operator tokens */
149 /* Arithmetic operator tokens */
152 %right UNARY_NEG
/* Dummy token for unary negation precedence */
154 %nonassoc NUM_REDUCT
/* Dummy token for numerical keyword reduction precedence */
156 /* Simple non-terminals */
157 %type
<i
> integer_number
158 %type
<r
> real_number number
161 %type
<smt
> str_match_type
163 /* Expression non-terminals */
164 %type
<sel
> commands command cmd_plain
165 %type
<sel
> selection
171 /* Parameter/value non-terminals */
172 %type
<plist
> method_params method_param_list
173 %type
<param
> method_param
174 %type
<vlist
> value_list value_list_contents basic_value_list basic_value_list_contents
175 %type
<val
> value_item value_item_range basic_value_item
176 %type
<vlist
> help_topic
178 %destructor
{ free
($$
); } HELP_TOPIC STR IDENTIFIER KEYWORD_POS CMP_OP
string
179 %destructor
{ if
($$
) free
($$
); } PARAM pos_mod
180 %destructor
{ delete $$
; } commands command cmd_plain selection
181 %destructor
{ delete $$
; } sel_expr num_expr str_expr pos_expr
182 %destructor
{ delete $$
; } method_params method_param_list method_param
183 %destructor
{ delete $$
; } value_list value_list_contents basic_value_list basic_value_list_contents
184 %destructor
{ delete $$
; } value_item value_item_range basic_value_item
185 %destructor
{ delete $$
; } help_topic
190 %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
))
214 /* A command is formed from an actual command and a separator */
215 command: cmd_plain CMD_SEP
{ $$
= $1; }
219 _gmx_selparser_error
(scanner
, "invalid selection '%s'",
220 _gmx_sel_lexer_pselstr
(scanner
));
221 _gmx_sel_lexer_clear_method_stack
(scanner
);
222 if
(_gmx_sel_is_lexer_interactive
(scanner
))
224 _gmx_sel_lexer_clear_pselstr
(scanner
);
236 /* Commands can be selections or variable assignments */
237 cmd_plain: /* empty */
240 _gmx_sel_handle_empty_cmd
(scanner
);
253 SelectionTreeElementPointer s
254 = _gmx_sel_init_group_by_id
($1, scanner
);
255 SelectionTreeElementPointer p
256 = _gmx_sel_init_position
(s
, NULL
, scanner
);
258 set
($$
, _gmx_sel_init_selection
(NULL
, p
, scanner
));
264 scoped_ptr_sfree nameGuard
($1);
265 SelectionTreeElementPointer s
266 = _gmx_sel_init_group_by_name
($1, scanner
);
267 SelectionTreeElementPointer p
268 = _gmx_sel_init_position
(s
, NULL
, scanner
);
270 set
($$
, _gmx_sel_init_selection
(NULL
, p
, scanner
));
276 set
($$
, _gmx_sel_init_selection
(NULL
, get
($1), scanner
));
282 scoped_ptr_sfree nameGuard
($1);
283 set
($$
, _gmx_sel_init_selection
($1, get
($2), scanner
));
286 | IDENTIFIER
'=' sel_expr
289 scoped_ptr_sfree nameGuard
($1);
290 set
($$
, _gmx_sel_assign_variable
($1, get
($3), scanner
));
293 | IDENTIFIER
'=' num_expr
296 scoped_ptr_sfree nameGuard
($1);
297 set
($$
, _gmx_sel_assign_variable
($1, get
($3), scanner
));
300 | IDENTIFIER
'=' pos_expr
303 scoped_ptr_sfree nameGuard
($1);
304 set
($$
, _gmx_sel_assign_variable
($1, get
($3), scanner
));
314 _gmx_sel_handle_help_cmd
(get
($2), scanner
);
319 help_topic: /* empty */
322 set
($$
, SelectionParserValue
::createList
());
325 | help_topic HELP_TOPIC
328 SelectionParserValueListPointer list
(get
($1));
329 list
->push_back
(SelectionParserValue
::createString
($2));
335 /* Selection is made of an expression and zero or more modifiers */
336 selection: pos_expr
{ $$
= $1; }
340 set
($$
, _gmx_sel_init_position
(get
($1), NULL
, scanner
));
344 |
'(' selection
')' { $$
= $2; }
345 | selection MODIFIER method_params
348 set
($$
, _gmx_sel_init_modifier
($2, get
($3), get
($1), scanner
));
354 /********************************************************************
355 * BASIC NON-TERMINAL SYMBOLS
356 ********************************************************************/
360 |
'-' TOK_INT
{ $$
= -$2; }
364 TOK_REAL
{ $$
= $1; }
365 |
'-' TOK_REAL
{ $$
= -$2; }
368 number: integer_number
{ $$
= $1; }
369 | real_number
{ $$
= $1; }
372 string: STR
{ $$
= $1; }
373 | IDENTIFIER
{ $$
= $1; }
376 /********************************************************************
377 * ATOM SELECTION EXPRESSIONS
378 ********************************************************************/
380 /* Boolean expressions and grouping */
381 sel_expr: NOT sel_expr
384 SelectionTreeElementPointer arg
(get
($2));
385 SelectionTreeElementPointer sel
(
386 new SelectionTreeElement
(SEL_BOOLEAN
));
387 sel
->u.boolt
= BOOL_NOT
;
392 | sel_expr AND sel_expr
395 SelectionTreeElementPointer arg1
(get
($1)), arg2
(get
($3));
396 SelectionTreeElementPointer sel
(
397 new SelectionTreeElement
(SEL_BOOLEAN
));
398 sel
->u.boolt
= BOOL_AND
;
399 sel
->child
= arg1
; sel
->child
->next
= arg2
;
403 | sel_expr OR sel_expr
406 SelectionTreeElementPointer arg1
(get
($1)), arg2
(get
($3));
407 SelectionTreeElementPointer sel
(
408 new SelectionTreeElement
(SEL_BOOLEAN
));
409 sel
->u.boolt
= BOOL_OR
;
410 sel
->child
= arg1
; sel
->child
->next
= arg2
;
414 |
'(' sel_expr
')' { $$
= $2; }
417 /* Numeric comparisons */
418 sel_expr: num_expr CMP_OP num_expr
421 scoped_ptr_sfree opGuard
($2);
422 set
($$
, _gmx_sel_init_comparison
(get
($1), get
($3), $2, scanner
));
428 /* External groups */
429 sel_expr: GROUP
string
432 scoped_ptr_sfree nameGuard
($2);
433 set
($$
, _gmx_sel_init_group_by_name
($2, scanner
));
439 set
($$
, _gmx_sel_init_group_by_id
($2, scanner
));
444 /* Position modifiers for selection methods */
445 pos_mod: EMPTY_POSMOD
{ $$
= NULL
; }
446 | KEYWORD_POS
{ $$
= $1; }
449 /* Matching mode forcing for keyword matching */
451 '~' { $$
= gmx
::eStringMatchType_RegularExpression
; }
452 |
'?' { $$
= gmx
::eStringMatchType_Wildcard
; }
453 |
'=' { $$
= gmx
::eStringMatchType_Exact
; }
456 /* Keyword selections */
457 sel_expr: pos_mod KEYWORD_GROUP
460 scoped_ptr_sfree posmodGuard
($1);
461 set
($$
, _gmx_sel_init_keyword
($2, SelectionParserValueListPointer
(), $1, scanner
));
465 | pos_mod KEYWORD_STR basic_value_list
468 scoped_ptr_sfree posmodGuard
($1);
469 set
($$
, _gmx_sel_init_keyword_strmatch
($2, gmx
::eStringMatchType_Auto
, get
($3), $1, scanner
));
473 | pos_mod KEYWORD_STR str_match_type basic_value_list
476 scoped_ptr_sfree posmodGuard
($1);
477 set
($$
, _gmx_sel_init_keyword_strmatch
($2, $3, get
($4), $1, scanner
));
481 | pos_mod KEYWORD_NUMERIC basic_value_list
484 scoped_ptr_sfree posmodGuard
($1);
485 set
($$
, _gmx_sel_init_keyword
($2, get
($3), $1, scanner
));
491 /* Custom selection methods */
492 sel_expr: pos_mod METHOD_GROUP method_params
495 scoped_ptr_sfree posmodGuard
($1);
496 set
($$
, _gmx_sel_init_method
($2, get
($3), $1, scanner
));
502 /********************************************************************
503 * NUMERICAL EXPRESSIONS
504 ********************************************************************/
506 /* Basic numerical values */
510 SelectionTreeElementPointer sel
(
511 new SelectionTreeElement
(SEL_CONST
));
512 _gmx_selelem_set_vtype
(sel
, INT_VALUE
);
513 _gmx_selvalue_reserve
(&sel
->v
, 1);
521 SelectionTreeElementPointer sel
(
522 new SelectionTreeElement
(SEL_CONST
));
523 _gmx_selelem_set_vtype
(sel
, REAL_VALUE
);
524 _gmx_selvalue_reserve
(&sel
->v
, 1);
531 /* Numeric selection methods */
532 num_expr: pos_mod KEYWORD_NUMERIC %prec NUM_REDUCT
535 scoped_ptr_sfree posmodGuard
($1);
536 set
($$
, _gmx_sel_init_keyword
($2, SelectionParserValueListPointer
(), $1, scanner
));
540 | pos_mod METHOD_NUMERIC method_params
543 scoped_ptr_sfree posmodGuard
($1);
544 set
($$
, _gmx_sel_init_method
($2, get
($3), $1, scanner
));
550 /* Arithmetic evaluation and grouping */
551 num_expr: num_expr
'+' num_expr
554 set
($$
, _gmx_sel_init_arithmetic
(get
($1), get
($3), '+', scanner
));
557 | num_expr
'-' num_expr
560 set
($$
, _gmx_sel_init_arithmetic
(get
($1), get
($3), '-', scanner
));
563 | num_expr
'*' num_expr
566 set
($$
, _gmx_sel_init_arithmetic
(get
($1), get
($3), '*', scanner
));
569 | num_expr
'/' num_expr
572 set
($$
, _gmx_sel_init_arithmetic
(get
($1), get
($3), '/', scanner
));
575 |
'-' num_expr %prec UNARY_NEG
578 set
($$
, _gmx_sel_init_arithmetic
(get
($2), SelectionTreeElementPointer
(), '-', scanner
));
581 | num_expr
'^' num_expr
584 set
($$
, _gmx_sel_init_arithmetic
(get
($1), get
($3), '^', scanner
));
587 |
'(' num_expr
')' { $$
= $2; }
590 /********************************************************************
592 ********************************************************************/
597 SelectionTreeElementPointer sel
(
598 new SelectionTreeElement
(SEL_CONST
));
599 _gmx_selelem_set_vtype
(sel
, STR_VALUE
);
600 _gmx_selvalue_reserve
(&sel
->v
, 1);
605 | pos_mod KEYWORD_STR
608 scoped_ptr_sfree posmodGuard
($1);
609 set
($$
, _gmx_sel_init_keyword
($2, SelectionParserValueListPointer
(), $1, scanner
));
615 /********************************************************************
616 * POSITION EXPRESSIONS
617 ********************************************************************/
619 /* Constant position expressions */
620 pos_expr: '[' number
',' number
',' number
']'
623 set
($$
, _gmx_sel_init_const_position
($2, $4, $6));
628 /* Grouping of position expressions */
629 pos_expr: '(' pos_expr
')' { $$
= $2; }
632 /* Expressions with a position value */
633 pos_expr: METHOD_POS method_params
636 set
($$
, _gmx_sel_init_method
($1, get
($2), NULL
, scanner
));
642 /* Evaluation of positions using a keyword */
643 pos_expr: KEYWORD_POS OF sel_expr %prec PARAM_REDUCT
646 scoped_ptr_sfree keywordGuard
($1);
647 set
($$
, _gmx_sel_init_position
(get
($3), $1, scanner
));
653 /********************************************************************
655 ********************************************************************/
657 sel_expr: VARIABLE_GROUP
660 set
($$
, _gmx_sel_init_variable_ref
(get
($1)));
665 num_expr: VARIABLE_NUMERIC
668 set
($$
, _gmx_sel_init_variable_ref
(get
($1)));
673 pos_expr: VARIABLE_POS
676 set
($$
, _gmx_sel_init_variable_ref
(get
($1)));
681 /********************************************************************
683 ********************************************************************/
688 | method_param_list END_OF_METHOD
696 set
($$
, SelectionParserParameter
::createList
());
699 | method_param_list method_param
702 SelectionParserParameterListPointer list
(get
($1));
703 list
->push_back
(get
($2));
713 scoped_ptr_sfree nameGuard
($1);
714 set
($$
, SelectionParserParameter
::create
($1, get
($2)));
719 value_list: value_list_contents
{ $$
= $1; }
720 |
'{' value_list_contents
'}' { $$
= $2; }
727 set
($$
, SelectionParserValue
::createList
());
730 | value_list_contents value_item
733 SelectionParserValueListPointer list
(get
($1));
734 list
->push_back
(get
($2));
738 | value_list_contents
',' value_item
741 SelectionParserValueListPointer list
(get
($1));
742 list
->push_back
(get
($3));
749 basic_value_list_contents
{ $$
= $1; }
750 |
'{' basic_value_list_contents
'}' { $$
= $2; }
753 basic_value_list_contents:
757 set
($$
, SelectionParserValue
::createList
(get
($1)));
760 | basic_value_list_contents basic_value_item
763 SelectionParserValueListPointer list
(get
($1));
764 list
->push_back
(get
($2));
768 | basic_value_list_contents
',' basic_value_item
771 SelectionParserValueListPointer list
(get
($1));
772 list
->push_back
(get
($3));
778 value_item: sel_expr %prec PARAM_REDUCT
781 set
($$
, SelectionParserValue
::createExpr
(get
($1)));
784 | pos_expr %prec PARAM_REDUCT
787 set
($$
, SelectionParserValue
::createExpr
(get
($1)));
790 | num_expr %prec PARAM_REDUCT
793 set
($$
, SelectionParserValue
::createExpr
(get
($1)));
796 | str_expr %prec PARAM_REDUCT
799 set
($$
, SelectionParserValue
::createExpr
(get
($1)));
802 | value_item_range
{ $$
= $1; }
806 integer_number %prec PARAM_REDUCT
809 set
($$
, SelectionParserValue
::createInteger
($1));
812 | real_number %prec PARAM_REDUCT
815 set
($$
, SelectionParserValue
::createReal
($1));
818 |
string %prec PARAM_REDUCT
821 scoped_ptr_sfree stringGuard
($1);
822 set
($$
, SelectionParserValue
::createString
($1));
825 | value_item_range
{ $$
= $1; }
829 integer_number TO integer_number
832 set
($$
, SelectionParserValue
::createIntegerRange
($1, $3));
835 | integer_number TO real_number
838 set
($$
, SelectionParserValue
::createRealRange
($1, $3));
841 | real_number TO number
844 set
($$
, SelectionParserValue
::createRealRange
($1, $3));