Code beautification with uncrustify
[alexxy/gromacs.git] / src / gromacs / selection / parsetree.h
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \internal \file
32  * \brief
33  * Handling of intermediate selection parser data.
34  *
35  * The data types declared in this header are used by the parser to store
36  * intermediate data when constructing method expressions.
37  * In particular, the parameters for the method are stored.
38  * The intermediate data is freed once a gmx::SelectionTreeElement object can
39  * be constructed.
40  *
41  * This is an implementation header: there should be no need to use it outside
42  * this directory.
43  *
44  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
45  * \ingroup module_selection
46  */
47 #ifndef GMX_SELECTION_PARSETREE_H
48 #define GMX_SELECTION_PARSETREE_H
49
50 #include <exception>
51 #include <list>
52 #include <string>
53
54 #include "gromacs/legacyheaders/types/simple.h"
55 #include "gromacs/legacyheaders/vec.h"
56
57 #include "gromacs/utility/gmxassert.h"
58 #include "gromacs/utility/uniqueptr.h"
59
60 #include "selelem.h"
61 #include "selvalue.h"
62
63 struct gmx_ana_indexgrps_t;
64 struct gmx_ana_selmethod_t;
65 struct gmx_ana_selparam_t;
66
67 namespace gmx
68 {
69
70 //! \cond internal
71 /*! \internal \brief
72  * String matching mode for string keyword expressions.
73  *
74  * \ingroup module_selection
75  */
76 enum SelectionStringMatchType
77 {
78     eStringMatchType_Auto,              //!< Deduce from the string.
79     eStringMatchType_Exact,             //!< Match as a literal string.
80     eStringMatchType_Wildcard,          //!< Match using ? and * as wildcards.
81     eStringMatchType_RegularExpression  //!< Match using regular expressions.
82 };
83 /*! \endcond */
84
85 class SelectionParserValue;
86
87 //! Container for a list of SelectionParserValue objects.
88 typedef std::list<SelectionParserValue>
89     SelectionParserValueList;
90 //! Smart pointer type for managing a SelectionParserValueList.
91 typedef gmx::gmx_unique_ptr<SelectionParserValueList>::type
92     SelectionParserValueListPointer;
93
94 /*! \internal \brief
95  * Describes a parsed value, possibly resulting from expression evaluation.
96  *
97  * All factory methods and the constructors may throw an std::bad_alloc if
98  * out of memory.
99  *
100  * \ingroup module_selection
101  */
102 class SelectionParserValue
103 {
104     public:
105         //! Allocates and initializes an empty value list.
106         static SelectionParserValueListPointer createList()
107         {
108             return SelectionParserValueListPointer(new SelectionParserValueList);
109         }
110         /*! \brief
111          * Allocates and initializes a value list with a single value.
112          *
113          * \param[in] value  Initial value to put in the list.
114          * \returns   Pointer to a new value list that contains \p value.
115          */
116         static SelectionParserValueListPointer
117         createList(const SelectionParserValue &value)
118         {
119             SelectionParserValueListPointer list(new SelectionParserValueList);
120             list->push_back(value);
121             return move(list);
122         }
123         /*! \brief
124          * Allocates and initializes an expression value.
125          *
126          * \param[in] expr  Root of the expression tree to assign to the value.
127          * \returns   The newly created value.
128          */
129         static SelectionParserValue
130         createExpr(const gmx::SelectionTreeElementPointer &expr)
131         {
132             return SelectionParserValue(expr);
133         }
134         /*! \brief
135          * Allocates and initializes a constant integer value.
136          *
137          * \param[in] value  Integer value to assign to the value.
138          * \returns   The newly created value.
139          */
140         static SelectionParserValue createInteger(int value)
141         {
142             SelectionParserValue result(INT_VALUE);
143             result.u.i.i1 = result.u.i.i2 = value;
144             return result;
145         }
146         /*! \brief
147          * Allocates and initializes a constant integer range value.
148          *
149          * \param[in] from  Beginning of the range to assign to the value.
150          * \param[in] to    End of the range to assign to the value.
151          * \returns   The newly created value.
152          */
153         static SelectionParserValue createIntegerRange(int from, int to)
154         {
155             SelectionParserValue result(INT_VALUE);
156             result.u.i.i1 = from;
157             result.u.i.i2 = to;
158             return result;
159         }
160         /*! \brief
161          * Allocates and initializes a constant floating-point value.
162          *
163          * \param[in] value  Floating-point value to assign to the value.
164          * \returns   The newly created value.
165          */
166         static SelectionParserValue createReal(real value)
167         {
168             SelectionParserValue result(REAL_VALUE);
169             result.u.r.r1 = result.u.r.r2 = value;
170             return result;
171         }
172         /*! \brief
173          * Allocates and initializes a constant floating-point range value.
174          *
175          * \param[in] from  Beginning of the range to assign to the value.
176          * \param[in] to    End of the range to assign to the value.
177          * \returns   The newly created value.
178          */
179         static SelectionParserValue createRealRange(real from, real to)
180         {
181             SelectionParserValue result(REAL_VALUE);
182             result.u.r.r1 = from;
183             result.u.r.r2 = to;
184             return result;
185         }
186         /*! \brief
187          * Allocates and initializes a constant string value.
188          *
189          * \param[in] value  String to assign to the value.
190          * \returns   The newly created value.
191          */
192         static SelectionParserValue createString(const char *value)
193         {
194             SelectionParserValue result(STR_VALUE);
195             result.str = value;
196             return result;
197         }
198         /*! \brief
199          * Allocates and initializes a constant position value.
200          *
201          * \param[in] value  Position vector to assign to the value.
202          * \returns   The newly created value.
203          */
204         static SelectionParserValue createPosition(rvec value)
205         {
206             SelectionParserValue result(POS_VALUE);
207             copy_rvec(value, result.u.x);
208             return result;
209         }
210
211         //! Returns true if the value comes from expression evaluation.
212         bool hasExpressionValue() const { return expr; }
213
214         //! Returns the string value (\a type must be ::STR_VALUE).
215         const std::string &stringValue() const
216         {
217             GMX_ASSERT(type == STR_VALUE && !hasExpressionValue(),
218                        "Attempted to retrieve string value from a non-string value");
219             return str;
220         }
221
222         // TODO: boost::any or similar could be nicer for the implementation.
223         //! Type of the value.
224         e_selvalue_t                     type;
225         //! Expression pointer if the value is the result of an expression.
226         gmx::SelectionTreeElementPointer expr;
227         //! String value for \a type ::STR_VALUE.
228         std::string                      str;
229         //! The actual value if \a expr is NULL and \a type is not ::STR_VALUE.
230         union {
231             //! The integer value/range (\a type ::INT_VALUE).
232             struct {
233                 //! Beginning of the range.
234                 int             i1;
235                 //! End of the range; equals \a i1 for a single integer.
236                 int             i2;
237             }                   i;
238             //! The real value/range (\a type ::REAL_VALUE).
239             struct {
240                 //! Beginning of the range.
241                 real            r1;
242                 //! End of the range; equals \a r1 for a single number.
243                 real            r2;
244             }                   r;
245             //! The position value (\a type ::POS_VALUE).
246             rvec                x;
247         }                       u;
248
249     private:
250         /*! \brief
251          * Initializes a new value.
252          *
253          * \param[in] type  Type for the new value.
254          */
255         explicit SelectionParserValue(e_selvalue_t type);
256         /*! \brief
257          * Initializes a new expression value.
258          *
259          * \param[in] expr  Expression for the value.
260          */
261         explicit SelectionParserValue(const gmx::SelectionTreeElementPointer &expr);
262 };
263
264 class SelectionParserParameter;
265
266 //! Container for a list of SelectionParserParameter objects.
267 typedef std::list<SelectionParserParameter>
268     SelectionParserParameterList;
269 //! Smart pointer type for managing a SelectionParserParameterList.
270 typedef gmx::gmx_unique_ptr<SelectionParserParameterList>::type
271     SelectionParserParameterListPointer;
272
273 /*! \internal \brief
274  * Describes a parsed method parameter.
275  *
276  * \ingroup module_selection
277  */
278 class SelectionParserParameter
279 {
280     public:
281         //! Allocates and initializes an empty parameter list.
282         static SelectionParserParameterListPointer createList()
283         {
284             return SelectionParserParameterListPointer(
285                     new SelectionParserParameterList);
286         }
287         /*! \brief
288          * Allocates and initializes a parsed method parameter.
289          *
290          * \param[in] name    Name for the new parameter (can be NULL).
291          * \param[in] values  List of values for the parameter.
292          * \returns   Pointer to the newly allocated parameter.
293          * \throws    std::bad_alloc if out of memory.
294          */
295         static SelectionParserParameter
296         create(const char *name, SelectionParserValueListPointer values)
297         {
298             return SelectionParserParameter(name, move(values));
299         }
300         //! \copydoc create(const char *, SelectionParserValueListPointer)
301         static SelectionParserParameter
302         create(const std::string &name, SelectionParserValueListPointer values)
303         {
304             return SelectionParserParameter(name.c_str(), move(values));
305         }
306         /*! \brief
307          * Allocates and initializes a parsed method parameter.
308          *
309          * \param[in] name    Name for the new parameter (can be NULL).
310          * \param[in] value   Value for the parameter.
311          * \returns   Pointer to the newly allocated parameter.
312          * \throws    std::bad_alloc if out of memory.
313          *
314          * This overload is a convenience wrapper for the case when creating
315          * parameters outside the actual Bison parser and only a single value
316          * is necessary.
317          */
318         static SelectionParserParameter
319         create(const char *name, const SelectionParserValue &value)
320         {
321             return create(name, SelectionParserValue::createList(value));
322         }
323         /*! \brief
324          * Allocates and initializes a parsed method parameter.
325          *
326          * \param[in] name    Name for the new parameter (can be NULL).
327          * \param[in] expr    Expression value for the parameter.
328          * \returns   Pointer to the newly allocated parameter.
329          * \throws    std::bad_alloc if out of memory.
330          *
331          * This overload is a convenience wrapper for the case when creating
332          * parameters outside the actual Bison parser and only a single
333          * expression value is necessary.
334          */
335         static SelectionParserParameter
336         createFromExpression(const char                        *name,
337                              const SelectionTreeElementPointer &expr)
338         {
339             return create(name, SelectionParserValue::createExpr(expr));
340         }
341         //! \copydoc createFromExpression(const char *, const SelectionTreeElementPointer &)
342         static SelectionParserParameter
343         createFromExpression(const std::string                 &name,
344                              const SelectionTreeElementPointer &expr)
345         {
346             return create(name.c_str(), SelectionParserValue::createExpr(expr));
347         }
348
349         /*! \brief
350          * Initializes a parsed method parameter.
351          *
352          * \param[in] name    Name for the new parameter (can be NULL).
353          * \param[in] values  List of values for the parameter.
354          * \throws    std::bad_alloc if out of memory.
355          */
356         SelectionParserParameter(const char                     *name,
357                                  SelectionParserValueListPointer values);
358
359         //! Returns the name of the parameter (may be empty).
360         const std::string &name() const { return name_; }
361         //! Returns the values for the parameter.
362         const SelectionParserValueList &values() const { return *values_; }
363
364         //! Name of the parameter.
365         std::string                     name_;
366         //! Values for this parameter.
367         SelectionParserValueListPointer values_;
368 };
369
370 } // namespace gmx
371
372 /** Error reporting function for the selection parser. */
373 void
374 _gmx_selparser_error(void *scanner, const char *fmt, ...);
375 /** Handle exceptions caught within the Bison code. */
376 bool
377 _gmx_selparser_handle_exception(void *scanner, const std::exception &ex);
378
379 /** Propagates the flags for selection elements. */
380 void
381 _gmx_selelem_update_flags(const gmx::SelectionTreeElementPointer &sel,
382                           void                                   *scanner);
383
384 /** Initializes the method parameter data of \ref SEL_EXPRESSION and
385  * \ref SEL_MODIFIER elements. */
386 void
387 _gmx_selelem_init_method_params(const gmx::SelectionTreeElementPointer &sel,
388                                 void                                   *scanner);
389 /** Initializes the method for a \ref SEL_EXPRESSION selection element. */
390 void
391 _gmx_selelem_set_method(const gmx::SelectionTreeElementPointer &sel,
392                         struct gmx_ana_selmethod_t *method, void *scanner);
393
394 /** Creates a gmx::SelectionTreeElement for arithmetic expression evaluation. */
395 gmx::SelectionTreeElementPointer
396 _gmx_sel_init_arithmetic(const gmx::SelectionTreeElementPointer &left,
397                          const gmx::SelectionTreeElementPointer &right,
398                          char op, void *scanner);
399 /** Creates a gmx::SelectionTreeElement for comparsion expression evaluation. */
400 gmx::SelectionTreeElementPointer
401 _gmx_sel_init_comparison(const gmx::SelectionTreeElementPointer &left,
402                          const gmx::SelectionTreeElementPointer &right,
403                          const char *cmpop, void *scanner);
404 /** Creates a gmx::SelectionTreeElement for a keyword expression from the parsed data. */
405 gmx::SelectionTreeElementPointer
406 _gmx_sel_init_keyword(struct gmx_ana_selmethod_t *method,
407                       gmx::SelectionParserValueListPointer args,
408                       const char *rpost, void *scanner);
409 /** Creates a gmx::SelectionTreeElement for string-matching keyword expression. */
410 gmx::SelectionTreeElementPointer
411 _gmx_sel_init_keyword_strmatch(struct gmx_ana_selmethod_t *method,
412                                gmx::SelectionStringMatchType matchType,
413                                gmx::SelectionParserValueListPointer args,
414                                const char *rpost, void *scanner);
415 /** Creates a gmx::SelectionTreeElement for a method expression from the parsed data. */
416 gmx::SelectionTreeElementPointer
417 _gmx_sel_init_method(struct gmx_ana_selmethod_t *method,
418                      gmx::SelectionParserParameterListPointer params,
419                      const char *rpost, void *scanner);
420 /** Creates a gmx::SelectionTreeElement for a modifier expression from the parsed data. */
421 gmx::SelectionTreeElementPointer
422 _gmx_sel_init_modifier(struct gmx_ana_selmethod_t              *mod,
423                        gmx::SelectionParserParameterListPointer params,
424                        const gmx::SelectionTreeElementPointer  &sel,
425                        void                                    *scanner);
426 /** Creates a gmx::SelectionTreeElement for evaluation of reference positions. */
427 gmx::SelectionTreeElementPointer
428 _gmx_sel_init_position(const gmx::SelectionTreeElementPointer &expr,
429                        const char *type, void *scanner);
430
431 /** Creates a gmx::SelectionTreeElement for a constant position. */
432 gmx::SelectionTreeElementPointer
433 _gmx_sel_init_const_position(real x, real y, real z);
434 /** Creates a gmx::SelectionTreeElement for a index group expression using group name. */
435 gmx::SelectionTreeElementPointer
436 _gmx_sel_init_group_by_name(const char *name, void *scanner);
437 /** Creates a gmx::SelectionTreeElement for a index group expression using group index. */
438 gmx::SelectionTreeElementPointer
439 _gmx_sel_init_group_by_id(int id, void *scanner);
440 /** Creates a gmx::SelectionTreeElement for a variable reference */
441 gmx::SelectionTreeElementPointer
442 _gmx_sel_init_variable_ref(const gmx::SelectionTreeElementPointer &sel);
443
444 /** Creates a root gmx::SelectionTreeElement for a selection. */
445 gmx::SelectionTreeElementPointer
446 _gmx_sel_init_selection(const char                             *name,
447                         const gmx::SelectionTreeElementPointer &sel,
448                         void                                   *scanner);
449 /** Creates a root gmx::SelectionTreeElement elements for a variable assignment. */
450 gmx::SelectionTreeElementPointer
451 _gmx_sel_assign_variable(const char                             *name,
452                          const gmx::SelectionTreeElementPointer &expr,
453                          void                                   *scanner);
454 /** Appends a root gmx::SelectionTreeElement to a selection collection. */
455 gmx::SelectionTreeElementPointer
456 _gmx_sel_append_selection(const gmx::SelectionTreeElementPointer &sel,
457                           gmx::SelectionTreeElementPointer        last,
458                           void                                   *scanner);
459 /** Check whether the parser should finish. */
460 bool
461 _gmx_sel_parser_should_finish(void *scanner);
462
463 /** Handle empty commands. */
464 void
465 _gmx_sel_handle_empty_cmd(void *scanner);
466 /** Process help commands. */
467 void
468 _gmx_sel_handle_help_cmd(const gmx::SelectionParserValueListPointer &topic,
469                          void                                       *scanner);
470
471 /* In params.c */
472 /** Initializes an array of parameters based on input from the selection parser. */
473 bool
474 _gmx_sel_parse_params(const gmx::SelectionParserParameterList &params,
475                       int nparam, struct gmx_ana_selparam_t *param,
476                       const gmx::SelectionTreeElementPointer &root,
477                       void *scanner);
478
479 #endif