128-bit AVX2 SIMD for AMD Ryzen
[gromacs.git] / src / gromacs / selection / parsetree.h
blob287fe89b6132f2e06f7bbc193ce213e07776a39e
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
35 /*! \internal \file
36 * \brief
37 * Handling of intermediate selection parser data.
39 * The data types declared in this header are used by the parser to store
40 * intermediate data when constructing method expressions.
41 * In particular, the parameters for the method are stored.
42 * The intermediate data is freed once a gmx::SelectionTreeElement object can
43 * be constructed.
45 * This is an implementation header: there should be no need to use it outside
46 * this directory.
48 * \author Teemu Murtola <teemu.murtola@gmail.com>
49 * \ingroup module_selection
51 #ifndef GMX_SELECTION_PARSETREE_H
52 #define GMX_SELECTION_PARSETREE_H
54 #include <exception>
55 #include <list>
56 #include <memory>
57 #include <string>
59 #include "gromacs/math/vec.h"
60 #include "gromacs/math/vectypes.h"
61 #include "gromacs/utility/gmxassert.h"
62 #include "gromacs/utility/real.h"
64 #include "selelem.h"
65 #include "selvalue.h"
67 struct gmx_ana_indexgrps_t;
68 struct gmx_ana_selmethod_t;
69 struct gmx_ana_selparam_t;
71 namespace gmx
74 //! \cond internal
75 /*! \internal \brief
76 * String matching mode for string keyword expressions.
78 * \ingroup module_selection
80 enum SelectionStringMatchType
82 eStringMatchType_Auto, //!< Deduce from the string.
83 eStringMatchType_Exact, //!< Match as a literal string.
84 eStringMatchType_Wildcard, //!< Match using ? and * as wildcards.
85 eStringMatchType_RegularExpression //!< Match using regular expressions.
87 /*! \endcond */
89 class SelectionParserValue;
91 //! Container for a list of SelectionParserValue objects.
92 typedef std::list<SelectionParserValue>
93 SelectionParserValueList;
94 //! Smart pointer type for managing a SelectionParserValueList.
95 typedef std::unique_ptr<SelectionParserValueList>
96 SelectionParserValueListPointer;
98 /*! \internal
99 * \brief
100 * Describes a parsed value, possibly resulting from expression evaluation.
102 * All factory methods and the constructors may throw an std::bad_alloc if
103 * out of memory.
105 * \ingroup module_selection
107 class SelectionParserValue
109 public:
110 //! Allocates and initializes an empty value list.
111 static SelectionParserValueListPointer createList()
113 return SelectionParserValueListPointer(new SelectionParserValueList);
115 /*! \brief
116 * Allocates and initializes a value list with a single value.
118 * \param[in] value Initial value to put in the list.
119 * \returns Pointer to a new value list that contains \p value.
121 static SelectionParserValueListPointer
122 createList(const SelectionParserValue &value)
124 SelectionParserValueListPointer list(new SelectionParserValueList);
125 list->push_back(value);
126 return list;
128 /*! \brief
129 * Allocates and initializes an expression value.
131 * \param[in] expr Root of the expression tree to assign to the value.
132 * \returns The newly created value.
134 static SelectionParserValue
135 createExpr(const gmx::SelectionTreeElementPointer &expr)
137 return SelectionParserValue(expr);
139 /*! \brief
140 * Allocates and initializes a constant integer value.
142 * \param[in] value Integer value to assign to the value.
143 * \param[in] location Location of the value.
144 * \returns The newly created value.
146 static SelectionParserValue
147 createInteger(int value, const SelectionLocation &location)
149 SelectionParserValue result(INT_VALUE, location);
150 result.u.i.i1 = result.u.i.i2 = value;
151 return result;
153 /*! \brief
154 * Allocates and initializes a constant integer range value.
156 * \param[in] from Beginning of the range to assign to the value.
157 * \param[in] to End of the range to assign to the value.
158 * \param[in] location Location of the value.
159 * \returns The newly created value.
161 static SelectionParserValue
162 createIntegerRange(int from, int to, const SelectionLocation &location)
164 SelectionParserValue result(INT_VALUE, location);
165 result.u.i.i1 = from;
166 result.u.i.i2 = to;
167 return result;
169 /*! \brief
170 * Allocates and initializes a constant floating-point value.
172 * \param[in] value Floating-point value to assign to the value.
173 * \param[in] location Location of the value.
174 * \returns The newly created value.
176 static SelectionParserValue
177 createReal(real value, const SelectionLocation &location)
179 SelectionParserValue result(REAL_VALUE, location);
180 result.u.r.r1 = result.u.r.r2 = value;
181 return result;
183 /*! \brief
184 * Allocates and initializes a constant floating-point range value.
186 * \param[in] from Beginning of the range to assign to the value.
187 * \param[in] to End of the range to assign to the value.
188 * \param[in] location Location of the value.
189 * \returns The newly created value.
191 static SelectionParserValue
192 createRealRange(real from, real to, const SelectionLocation &location)
194 SelectionParserValue result(REAL_VALUE, location);
195 result.u.r.r1 = from;
196 result.u.r.r2 = to;
197 return result;
199 /*! \brief
200 * Allocates and initializes a constant string value.
202 * \param[in] value String to assign to the value.
203 * \param[in] location Location of the value.
204 * \returns The newly created value.
206 static SelectionParserValue
207 createString(const char *value, const SelectionLocation &location)
209 SelectionParserValue result(STR_VALUE, location);
210 result.str = value;
211 return result;
213 /*! \brief
214 * Allocates and initializes a constant position value.
216 * \param[in] value Position vector to assign to the value.
217 * \param[in] location Location of the value.
218 * \returns The newly created value.
220 static SelectionParserValue
221 createPosition(rvec value, const SelectionLocation &location)
223 SelectionParserValue result(POS_VALUE, location);
224 copy_rvec(value, result.u.x);
225 return result;
228 //! Returns the location of this value in the parsed selection text.
229 const SelectionLocation &location() const { return location_; }
230 //! Returns true if the value comes from expression evaluation.
231 bool hasExpressionValue() const { return static_cast<bool>(expr); }
233 //! Returns the string value (\a type must be ::STR_VALUE).
234 const std::string &stringValue() const
236 GMX_ASSERT(type == STR_VALUE && !hasExpressionValue(),
237 "Attempted to retrieve string value from a non-string value");
238 return str;
241 // TODO: boost::any or similar could be nicer for the implementation.
242 //! Type of the value.
243 e_selvalue_t type;
244 //! Expression pointer if the value is the result of an expression.
245 gmx::SelectionTreeElementPointer expr;
246 //! String value for \a type ::STR_VALUE.
247 std::string str;
248 //! The actual value if \a expr is NULL and \a type is not ::STR_VALUE.
249 union {
250 //! The integer value/range (\a type ::INT_VALUE).
251 struct {
252 //! Beginning of the range.
253 int i1;
254 //! End of the range; equals \a i1 for a single integer.
255 int i2;
256 } i;
257 //! The real value/range (\a type ::REAL_VALUE).
258 struct {
259 //! Beginning of the range.
260 real r1;
261 //! End of the range; equals \a r1 for a single number.
262 real r2;
263 } r;
264 //! The position value (\a type ::POS_VALUE).
265 rvec x;
266 } u;
268 private:
269 /*! \brief
270 * Initializes a new value.
272 * \param[in] type Type for the new value.
273 * \param[in] location Location for the value.
275 SelectionParserValue(e_selvalue_t type, const SelectionLocation &location);
276 /*! \brief
277 * Initializes a new expression value.
279 * \param[in] expr Expression for the value.
281 explicit SelectionParserValue(const gmx::SelectionTreeElementPointer &expr);
283 //! Location of the value in the parsed text.
284 SelectionLocation location_;
287 class SelectionParserParameter;
289 //! Container for a list of SelectionParserParameter objects.
290 typedef std::list<SelectionParserParameter>
291 SelectionParserParameterList;
292 //! Smart pointer type for managing a SelectionParserParameterList.
293 typedef std::unique_ptr<SelectionParserParameterList>
294 SelectionParserParameterListPointer;
296 /*! \internal \brief
297 * Describes a parsed method parameter.
299 * \ingroup module_selection
301 class SelectionParserParameter
303 public:
304 // Default move constructor and assignment. Only needed for old compilers.
305 //! \cond
306 SelectionParserParameter(SelectionParserParameter &&o)
307 : name_(std::move(o.name_)), location_(std::move(o.location_)),
308 values_(std::move(o.values_))
312 SelectionParserParameter &operator=(SelectionParserParameter &&o)
314 name_ = std::move(o.name_);
315 location_ = std::move(o.location_);
316 values_ = std::move(o.values_);
317 return *this;
319 //! \endcond
321 //! Allocates and initializes an empty parameter list.
322 static SelectionParserParameterListPointer createList()
324 return SelectionParserParameterListPointer(
325 new SelectionParserParameterList);
327 /*! \brief
328 * Allocates and initializes a parsed method parameter.
330 * \param[in] name Name for the new parameter (can be NULL).
331 * \param[in] values List of values for the parameter.
332 * \param[in] location Location of the parameter.
333 * \returns Pointer to the newly allocated parameter.
334 * \throws std::bad_alloc if out of memory.
336 static SelectionParserParameter
337 create(const char *name, SelectionParserValueListPointer values,
338 const SelectionLocation &location)
340 return SelectionParserParameter(name, std::move(values), location);
342 //! \copydoc create(const char *, SelectionParserValueListPointer, const SelectionLocation &)
343 static SelectionParserParameter
344 create(const std::string &name, SelectionParserValueListPointer values,
345 const SelectionLocation &location)
347 return SelectionParserParameter(name.c_str(), std::move(values), location);
349 /*! \brief
350 * Allocates and initializes a parsed method parameter.
352 * \param[in] name Name for the new parameter (can be NULL).
353 * \param[in] value Value for the parameter.
354 * \param[in] location Location of the parameter.
355 * \returns Pointer to the newly allocated parameter.
356 * \throws std::bad_alloc if out of memory.
358 * This overload is a convenience wrapper for the case when creating
359 * parameters outside the actual Bison parser and only a single value
360 * is necessary.
362 static SelectionParserParameter
363 create(const char *name, const SelectionParserValue &value,
364 const SelectionLocation &location)
366 return create(name, SelectionParserValue::createList(value), location);
368 /*! \brief
369 * Allocates and initializes a parsed method parameter.
371 * \param[in] name Name for the new parameter (can be NULL).
372 * \param[in] expr Expression value for the parameter.
373 * \returns Pointer to the newly allocated parameter.
374 * \throws std::bad_alloc if out of memory.
376 * This overload is a convenience wrapper for the case when creating
377 * parameters outside the actual Bison parser and only a single
378 * expression value is necessary.
380 static SelectionParserParameter
381 createFromExpression(const char *name,
382 const SelectionTreeElementPointer &expr)
384 return create(name, SelectionParserValue::createExpr(expr),
385 expr->location());
387 //! \copydoc createFromExpression(const char *, const SelectionTreeElementPointer &)
388 static SelectionParserParameter
389 createFromExpression(const std::string &name,
390 const SelectionTreeElementPointer &expr)
392 return create(name.c_str(), SelectionParserValue::createExpr(expr),
393 expr->location());
396 //! Returns the name of the parameter (may be empty).
397 const std::string &name() const { return name_; }
398 //! Returns the location of this parameter in the parsed selection text.
399 const SelectionLocation &location() const { return location_; }
400 //! Returns the values for the parameter.
401 const SelectionParserValueList &values() const { return *values_; }
403 private:
404 /*! \brief
405 * Initializes a parsed method parameter.
407 * \param[in] name Name for the new parameter (can be NULL).
408 * \param[in] values List of values for the parameter.
409 * \param[in] location Location of the parameter.
410 * \throws std::bad_alloc if out of memory.
412 SelectionParserParameter(const char *name,
413 SelectionParserValueListPointer values,
414 const SelectionLocation &location);
416 //! Name of the parameter.
417 std::string name_;
418 //! Location of the parameter in the parsed text.
419 SelectionLocation location_;
421 // TODO: Make private, there is only one direct user.
422 public:
423 //! Values for this parameter.
424 SelectionParserValueListPointer values_;
427 } // namespace gmx
429 /*! \brief
430 * Handles exceptions caught within the Bison code.
432 * \retval `true` if the parser should attempt error recovery.
433 * \retval `false` if the parser should immediately abort.
435 * This function is called whenever an exception is caught within Bison
436 * actions. Since exceptions cannot propagate through Bison code, the
437 * exception is saved (potentially with some extra context information) so that
438 * the caller of the parser can rethrow the exception.
440 * If it is possible to recover from the exception, then the function returns
441 * `true`, and Bison enters error recovery state. At the end of the recovery,
442 * _gmx_selparser_handle_error() is called.
443 * If this function returns false, then Bison immediately aborts the parsing
444 * so that the caller can rethrow the exception.
446 bool
447 _gmx_selparser_handle_exception(void *scanner, std::exception *ex);
448 /*! \brief
449 * Handles errors in the selection parser.
451 * \returns `true` if parsing can continue with the next selection.
452 * \throws std::bad_alloc if out of memory during the error processing.
453 * \throws unspecified Can throw the stored exception if recovery from that
454 * exception is not possible.
456 * This function is called during error recovery, after Bison has discarded all
457 * the symbols for the erroneous selection.
458 * At this point, the full selection that caused the error is known, and can be
459 * added to the error context.
461 * For an interactive parser, this function returns `true` to let the parsing
462 * continue with the next selection, or to let the user enter the next
463 * selection, if it was possible to recover from the exception.
464 * For other cases, this will either rethrow the original exception with added
465 * context, or return `false` after adding the context to the error reporter.
466 * Any exceptions thrown from this method are again caught by Bison and result
467 * in termination of the parsing; the caller can then rethrow them.
469 bool
470 _gmx_selparser_handle_error(void *scanner);
472 /** Propagates the flags for selection elements. */
473 void
474 _gmx_selelem_update_flags(const gmx::SelectionTreeElementPointer &sel);
476 /** Initializes the method parameter data of \ref SEL_EXPRESSION and
477 * \ref SEL_MODIFIER elements. */
478 void
479 _gmx_selelem_init_method_params(const gmx::SelectionTreeElementPointer &sel,
480 void *scanner);
481 /** Initializes the method for a \ref SEL_EXPRESSION selection element. */
482 void
483 _gmx_selelem_set_method(const gmx::SelectionTreeElementPointer &sel,
484 struct gmx_ana_selmethod_t *method, void *scanner);
486 /* An opaque pointer. */
487 #ifndef YY_TYPEDEF_YY_SCANNER_T
488 #define YY_TYPEDEF_YY_SCANNER_T
489 typedef void* yyscan_t;
490 #endif
491 /** \brief Creates a gmx::SelectionTreeElement for arithmetic expression evaluation.
493 * \param[in] left Selection element for the left hand side.
494 * \param[in] right Selection element for the right hand side.
495 * \param[in] op String representation of the operator.
496 * \param[in] scanner Scanner data structure.
497 * \returns The created selection element.
499 * This function handles the creation of a gmx::SelectionTreeElement object for
500 * arithmetic expressions.
502 gmx::SelectionTreeElementPointer
503 _gmx_sel_init_arithmetic(const gmx::SelectionTreeElementPointer &left,
504 const gmx::SelectionTreeElementPointer &right,
505 char op, yyscan_t scanner);
506 /** Creates a gmx::SelectionTreeElement for comparsion expression evaluation. */
507 gmx::SelectionTreeElementPointer
508 _gmx_sel_init_comparison(const gmx::SelectionTreeElementPointer &left,
509 const gmx::SelectionTreeElementPointer &right,
510 const char *cmpop, void *scanner);
511 /** Creates a gmx::SelectionTreeElement for a keyword expression from the parsed data. */
512 gmx::SelectionTreeElementPointer
513 _gmx_sel_init_keyword(struct gmx_ana_selmethod_t *method,
514 gmx::SelectionParserValueListPointer args,
515 const char *rpost, void *scanner);
516 /** Creates a gmx::SelectionTreeElement for string-matching keyword expression. */
517 gmx::SelectionTreeElementPointer
518 _gmx_sel_init_keyword_strmatch(struct gmx_ana_selmethod_t *method,
519 gmx::SelectionStringMatchType matchType,
520 gmx::SelectionParserValueListPointer args,
521 const char *rpost, void *scanner);
522 /** Creates a gmx::SelectionTreeElement for "keyword of" expression. */
523 gmx::SelectionTreeElementPointer
524 _gmx_sel_init_keyword_of(struct gmx_ana_selmethod_t *method,
525 const gmx::SelectionTreeElementPointer &group,
526 const char *rpost, void *scanner);
527 /** Creates a gmx::SelectionTreeElement for a method expression from the parsed data. */
528 gmx::SelectionTreeElementPointer
529 _gmx_sel_init_method(struct gmx_ana_selmethod_t *method,
530 gmx::SelectionParserParameterListPointer params,
531 const char *rpost, void *scanner);
532 /** Creates a gmx::SelectionTreeElement for a modifier expression from the parsed data. */
533 gmx::SelectionTreeElementPointer
534 _gmx_sel_init_modifier(struct gmx_ana_selmethod_t *mod,
535 gmx::SelectionParserParameterListPointer params,
536 const gmx::SelectionTreeElementPointer &sel,
537 void *scanner);
538 /** Creates a gmx::SelectionTreeElement for evaluation of reference positions. */
539 gmx::SelectionTreeElementPointer
540 _gmx_sel_init_position(const gmx::SelectionTreeElementPointer &expr,
541 const char *type, void *scanner);
543 /** Creates a gmx::SelectionTreeElement for a constant position. */
544 gmx::SelectionTreeElementPointer
545 _gmx_sel_init_const_position(real x, real y, real z, void *scanner);
546 /** Creates a gmx::SelectionTreeElement for a index group expression using group name. */
547 gmx::SelectionTreeElementPointer
548 _gmx_sel_init_group_by_name(const char *name, void *scanner);
549 /** Creates a gmx::SelectionTreeElement for a index group expression using group index. */
550 gmx::SelectionTreeElementPointer
551 _gmx_sel_init_group_by_id(int id, void *scanner);
552 /** Creates a gmx::SelectionTreeElement for a variable reference */
553 gmx::SelectionTreeElementPointer
554 _gmx_sel_init_variable_ref(const gmx::SelectionTreeElementPointer &sel,
555 void *scanner);
557 /** Creates a root gmx::SelectionTreeElement for a selection. */
558 gmx::SelectionTreeElementPointer
559 _gmx_sel_init_selection(const char *name,
560 const gmx::SelectionTreeElementPointer &sel,
561 void *scanner);
562 /** Creates a root gmx::SelectionTreeElement elements for a variable assignment. */
563 gmx::SelectionTreeElementPointer
564 _gmx_sel_assign_variable(const char *name,
565 const gmx::SelectionTreeElementPointer &expr,
566 void *scanner);
567 /** Appends a root gmx::SelectionTreeElement to a selection collection. */
568 gmx::SelectionTreeElementPointer
569 _gmx_sel_append_selection(const gmx::SelectionTreeElementPointer &sel,
570 gmx::SelectionTreeElementPointer last,
571 void *scanner);
572 /** Check whether the parser should finish. */
573 bool
574 _gmx_sel_parser_should_finish(void *scanner);
576 /* In params.c */
577 /** Initializes an array of parameters based on input from the selection parser. */
578 void
579 _gmx_sel_parse_params(const gmx::SelectionParserParameterList &params,
580 int nparam, struct gmx_ana_selparam_t *param,
581 const gmx::SelectionTreeElementPointer &root,
582 void *scanner);
584 #endif