3 * This file is part of the GROMACS molecular simulation package.
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.
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/utility/scoped_ptr_sfree.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 /* Simple input tokens */
100 %token <str> IDENTIFIER
103 /* Simple keyword tokens */
107 /* Variable tokens */
108 %token <sel> VARIABLE_NUMERIC
109 %token <sel> VARIABLE_GROUP
110 %token <sel> VARIABLE_POS
112 /* Selection method tokens */
113 %token <meth> KEYWORD_NUMERIC
114 %token <meth> KEYWORD_STR
115 %token <str> KEYWORD_POS
116 %token <meth> KEYWORD_GROUP
117 %token <meth> METHOD_NUMERIC
118 %token <meth> METHOD_GROUP
119 %token <meth> METHOD_POS
120 %token <meth> MODIFIER
121 /* Empty token that should precede any non-position KEYWORD/METHOD token that
122 * is not preceded by KEYWORD_POS. This is used to work around reduce/reduce
123 * conflicts that appear when a lookahead token would require a reduction of
124 * a rule with empty RHS before shifting, and there is an alternative reduction
125 * available. Replacing the empty RHS with a dummy token makes these conflicts
126 * only shift/reduce conflicts. Another alternative would be to remove the
127 * pos_mod non-terminal completely and split each rule that uses it into two,
128 * but this would require duplicating six rules in the grammar. */
135 /* Comparison operators have lower precedence than parameter reduction
136 * to make it possible to parse, e.g., "mindist from resnr 1 < 2" without
138 %nonassoc <str> CMP_OP
139 /* A dummy token that determines the precedence of parameter reduction */
140 %nonassoc PARAM_REDUCT
141 /* Boolean operator tokens */
145 /* Arithmetic operator tokens */
148 %right UNARY_NEG /* Dummy token for unary negation precedence */
150 %nonassoc NUM_REDUCT /* Dummy token for numerical keyword reduction precedence */
152 /* Simple non-terminals */
153 %type <i> integer_number
154 %type <r> real_number number
157 %type <smt> str_match_type
159 /* Expression non-terminals */
160 %type <sel> commands command cmd_plain
161 %type <sel> selection
167 /* Parameter/value non-terminals */
168 %type <plist> method_params method_param_list
169 %type <param> method_param
170 %type <vlist> value_list value_list_contents basic_value_list basic_value_list_contents
171 %type <val> value_item value_item_range basic_value_item
173 %destructor { free($$); } STR IDENTIFIER KEYWORD_POS CMP_OP string
174 %destructor { if($$) free($$); } PARAM pos_mod
175 %destructor { delete $$; } commands command cmd_plain selection
176 %destructor { delete $$; } sel_expr num_expr str_expr pos_expr
177 %destructor { delete $$; } method_params method_param_list method_param
178 %destructor { delete $$; } value_list value_list_contents basic_value_list basic_value_list_contents
179 %destructor { delete $$; } value_item value_item_range basic_value_item
184 %define api.push-pull push
186 %name-prefix="_gmx_sel_yy"
187 %parse-param { void *scanner }
191 /* The start rule: allow one or more commands */
192 commands: /* empty */
201 set($$, _gmx_sel_append_selection(get($2), get($1), scanner));
202 if (_gmx_sel_parser_should_finish(scanner))
208 /* A command is formed from an actual command and a separator */
209 command: cmd_plain CMD_SEP { $$ = $1; }
213 _gmx_selparser_error(scanner, "invalid selection '%s'",
214 _gmx_sel_lexer_pselstr(scanner));
215 _gmx_sel_lexer_clear_method_stack(scanner);
216 if (_gmx_sel_is_lexer_interactive(scanner))
218 _gmx_sel_lexer_clear_pselstr(scanner);
230 /* Commands can be selections or variable assignments */
231 cmd_plain: /* empty */
240 SelectionTreeElementPointer s
241 = _gmx_sel_init_group_by_id($1, scanner);
242 SelectionTreeElementPointer p
243 = _gmx_sel_init_position(s, NULL, scanner);
245 set($$, _gmx_sel_init_selection(NULL, p, scanner));
251 scoped_ptr_sfree nameGuard($1);
252 SelectionTreeElementPointer s
253 = _gmx_sel_init_group_by_name($1, scanner);
254 SelectionTreeElementPointer p
255 = _gmx_sel_init_position(s, NULL, scanner);
257 set($$, _gmx_sel_init_selection(NULL, p, scanner));
263 set($$, _gmx_sel_init_selection(NULL, get($1), scanner));
269 scoped_ptr_sfree nameGuard($1);
270 set($$, _gmx_sel_init_selection($1, get($2), scanner));
273 | IDENTIFIER '=' sel_expr
276 scoped_ptr_sfree nameGuard($1);
277 set($$, _gmx_sel_assign_variable($1, get($3), scanner));
280 | IDENTIFIER '=' num_expr
283 scoped_ptr_sfree nameGuard($1);
284 set($$, _gmx_sel_assign_variable($1, get($3), scanner));
287 | IDENTIFIER '=' pos_expr
290 scoped_ptr_sfree nameGuard($1);
291 set($$, _gmx_sel_assign_variable($1, get($3), scanner));
296 /* Selection is made of an expression and zero or more modifiers */
297 selection: pos_expr { $$ = $1; }
301 set($$, _gmx_sel_init_position(get($1), NULL, scanner));
305 | '(' selection ')' { $$ = $2; }
306 | selection MODIFIER method_params
309 set($$, _gmx_sel_init_modifier($2, get($3), get($1), scanner));
315 /********************************************************************
316 * BASIC NON-TERMINAL SYMBOLS
317 ********************************************************************/
321 | '-' TOK_INT { $$ = -$2; }
325 TOK_REAL { $$ = $1; }
326 | '-' TOK_REAL { $$ = -$2; }
329 number: integer_number { $$ = $1; }
330 | real_number { $$ = $1; }
333 string: STR { $$ = $1; }
334 | IDENTIFIER { $$ = $1; }
337 /********************************************************************
338 * ATOM SELECTION EXPRESSIONS
339 ********************************************************************/
341 /* Boolean expressions and grouping */
342 sel_expr: NOT sel_expr
345 SelectionTreeElementPointer arg(get($2));
346 SelectionTreeElementPointer sel(
347 new SelectionTreeElement(SEL_BOOLEAN));
348 sel->u.boolt = BOOL_NOT;
353 | sel_expr AND sel_expr
356 SelectionTreeElementPointer arg1(get($1)), arg2(get($3));
357 SelectionTreeElementPointer sel(
358 new SelectionTreeElement(SEL_BOOLEAN));
359 sel->u.boolt = BOOL_AND;
360 sel->child = arg1; sel->child->next = arg2;
364 | sel_expr OR sel_expr
367 SelectionTreeElementPointer arg1(get($1)), arg2(get($3));
368 SelectionTreeElementPointer sel(
369 new SelectionTreeElement(SEL_BOOLEAN));
370 sel->u.boolt = BOOL_OR;
371 sel->child = arg1; sel->child->next = arg2;
375 | '(' sel_expr ')' { $$ = $2; }
378 /* Numeric comparisons */
379 sel_expr: num_expr CMP_OP num_expr
382 scoped_ptr_sfree opGuard($2);
383 set($$, _gmx_sel_init_comparison(get($1), get($3), $2, scanner));
389 /* External groups */
390 sel_expr: GROUP string
393 scoped_ptr_sfree nameGuard($2);
394 set($$, _gmx_sel_init_group_by_name($2, scanner));
400 set($$, _gmx_sel_init_group_by_id($2, scanner));
405 /* Position modifiers for selection methods */
406 pos_mod: EMPTY_POSMOD { $$ = NULL; }
407 | KEYWORD_POS { $$ = $1; }
410 /* Matching mode forcing for keyword matching */
412 '~' { $$ = gmx::eStringMatchType_RegularExpression; }
413 | '?' { $$ = gmx::eStringMatchType_Wildcard; }
414 | '=' { $$ = gmx::eStringMatchType_Exact; }
417 /* Keyword selections */
418 sel_expr: pos_mod KEYWORD_GROUP
421 scoped_ptr_sfree posmodGuard($1);
422 set($$, _gmx_sel_init_keyword($2, SelectionParserValueListPointer(), $1, scanner));
426 | pos_mod KEYWORD_STR basic_value_list
429 scoped_ptr_sfree posmodGuard($1);
430 set($$, _gmx_sel_init_keyword_strmatch($2, gmx::eStringMatchType_Auto, get($3), $1, scanner));
434 | pos_mod KEYWORD_STR str_match_type basic_value_list
437 scoped_ptr_sfree posmodGuard($1);
438 set($$, _gmx_sel_init_keyword_strmatch($2, $3, get($4), $1, scanner));
442 | pos_mod KEYWORD_NUMERIC basic_value_list
445 scoped_ptr_sfree posmodGuard($1);
446 set($$, _gmx_sel_init_keyword($2, get($3), $1, scanner));
452 /* Custom selection methods */
453 sel_expr: pos_mod METHOD_GROUP method_params
456 scoped_ptr_sfree posmodGuard($1);
457 set($$, _gmx_sel_init_method($2, get($3), $1, scanner));
463 /********************************************************************
464 * NUMERICAL EXPRESSIONS
465 ********************************************************************/
467 /* Basic numerical values */
471 SelectionTreeElementPointer sel(
472 new SelectionTreeElement(SEL_CONST));
473 _gmx_selelem_set_vtype(sel, INT_VALUE);
474 _gmx_selvalue_reserve(&sel->v, 1);
482 SelectionTreeElementPointer sel(
483 new SelectionTreeElement(SEL_CONST));
484 _gmx_selelem_set_vtype(sel, REAL_VALUE);
485 _gmx_selvalue_reserve(&sel->v, 1);
492 /* Numeric selection methods */
493 num_expr: pos_mod KEYWORD_NUMERIC %prec NUM_REDUCT
496 scoped_ptr_sfree posmodGuard($1);
497 set($$, _gmx_sel_init_keyword($2, SelectionParserValueListPointer(), $1, scanner));
501 | pos_mod METHOD_NUMERIC method_params
504 scoped_ptr_sfree posmodGuard($1);
505 set($$, _gmx_sel_init_method($2, get($3), $1, scanner));
511 /* Arithmetic evaluation and grouping */
512 num_expr: num_expr '+' num_expr
515 set($$, _gmx_sel_init_arithmetic(get($1), get($3), '+', scanner));
518 | num_expr '-' num_expr
521 set($$, _gmx_sel_init_arithmetic(get($1), get($3), '-', scanner));
524 | num_expr '*' num_expr
527 set($$, _gmx_sel_init_arithmetic(get($1), get($3), '*', scanner));
530 | num_expr '/' num_expr
533 set($$, _gmx_sel_init_arithmetic(get($1), get($3), '/', scanner));
536 | '-' num_expr %prec UNARY_NEG
539 set($$, _gmx_sel_init_arithmetic(get($2), SelectionTreeElementPointer(), '-', scanner));
542 | num_expr '^' num_expr
545 set($$, _gmx_sel_init_arithmetic(get($1), get($3), '^', scanner));
548 | '(' num_expr ')' { $$ = $2; }
551 /********************************************************************
553 ********************************************************************/
558 SelectionTreeElementPointer sel(
559 new SelectionTreeElement(SEL_CONST));
560 _gmx_selelem_set_vtype(sel, STR_VALUE);
561 _gmx_selvalue_reserve(&sel->v, 1);
566 | pos_mod KEYWORD_STR
569 scoped_ptr_sfree posmodGuard($1);
570 set($$, _gmx_sel_init_keyword($2, SelectionParserValueListPointer(), $1, scanner));
576 /********************************************************************
577 * POSITION EXPRESSIONS
578 ********************************************************************/
580 /* Constant position expressions */
581 pos_expr: '[' number ',' number ',' number ']'
584 set($$, _gmx_sel_init_const_position($2, $4, $6));
589 /* Grouping of position expressions */
590 pos_expr: '(' pos_expr ')' { $$ = $2; }
593 /* Expressions with a position value */
594 pos_expr: METHOD_POS method_params
597 set($$, _gmx_sel_init_method($1, get($2), NULL, scanner));
603 /* Evaluation of positions using a keyword */
604 pos_expr: KEYWORD_POS OF sel_expr %prec PARAM_REDUCT
607 scoped_ptr_sfree keywordGuard($1);
608 set($$, _gmx_sel_init_position(get($3), $1, scanner));
614 /********************************************************************
616 ********************************************************************/
618 sel_expr: VARIABLE_GROUP
621 set($$, _gmx_sel_init_variable_ref(get($1)));
626 num_expr: VARIABLE_NUMERIC
629 set($$, _gmx_sel_init_variable_ref(get($1)));
634 pos_expr: VARIABLE_POS
637 set($$, _gmx_sel_init_variable_ref(get($1)));
642 /********************************************************************
644 ********************************************************************/
649 | method_param_list END_OF_METHOD
657 set($$, SelectionParserParameter::createList());
660 | method_param_list method_param
663 SelectionParserParameterListPointer list(get($1));
664 list->push_back(get($2));
674 scoped_ptr_sfree nameGuard($1);
675 set($$, SelectionParserParameter::create($1, get($2)));
680 value_list: value_list_contents { $$ = $1; }
681 | '{' value_list_contents '}' { $$ = $2; }
688 set($$, SelectionParserValue::createList());
691 | value_list_contents value_item
694 SelectionParserValueListPointer list(get($1));
695 list->push_back(get($2));
699 | value_list_contents ',' value_item
702 SelectionParserValueListPointer list(get($1));
703 list->push_back(get($3));
710 basic_value_list_contents { $$ = $1; }
711 | '{' basic_value_list_contents '}' { $$ = $2; }
714 basic_value_list_contents:
718 set($$, SelectionParserValue::createList(get($1)));
721 | basic_value_list_contents basic_value_item
724 SelectionParserValueListPointer list(get($1));
725 list->push_back(get($2));
729 | basic_value_list_contents ',' basic_value_item
732 SelectionParserValueListPointer list(get($1));
733 list->push_back(get($3));
739 value_item: sel_expr %prec PARAM_REDUCT
742 set($$, SelectionParserValue::createExpr(get($1)));
745 | pos_expr %prec PARAM_REDUCT
748 set($$, SelectionParserValue::createExpr(get($1)));
751 | num_expr %prec PARAM_REDUCT
754 set($$, SelectionParserValue::createExpr(get($1)));
757 | str_expr %prec PARAM_REDUCT
760 set($$, SelectionParserValue::createExpr(get($1)));
763 | value_item_range { $$ = $1; }
767 integer_number %prec PARAM_REDUCT
770 set($$, SelectionParserValue::createInteger($1));
773 | real_number %prec PARAM_REDUCT
776 set($$, SelectionParserValue::createReal($1));
779 | string %prec PARAM_REDUCT
782 scoped_ptr_sfree stringGuard($1);
783 set($$, SelectionParserValue::createString($1));
786 | value_item_range { $$ = $1; }
790 integer_number TO integer_number
793 set($$, SelectionParserValue::createIntegerRange($1, $3));
796 | integer_number TO real_number
799 set($$, SelectionParserValue::createRealRange($1, $3));
802 | real_number TO number
805 set($$, SelectionParserValue::createRealRange($1, $3));