C++ classes for selection parser parameters.
[alexxy/gromacs.git] / src / gromacs / selection / parser_internal.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 Helper functions for the selection parser.
33  *
34  * This header is includes only from parser.cpp (generated from parser.y), and
35  * it includes functions and macros used internally by the parser.
36  * They are in a separate file to make then easier to edit (no need to
37  * regenerate the parser), and to keep parser.y as simple as possible.
38  *
39  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
40  * \ingroup module_selection
41  */
42 #ifndef GMX_SELECTION_PARSER_INTERNAL_H
43 #define GMX_SELECTION_PARSER_INTERNAL_H
44
45 #include <exception>
46
47 #include "parsetree.h"
48 #include "selelem.h"
49
50 #include "scanner.h"
51
52 //! Helper method to reorder a list of parameter values.
53 static t_selexpr_value *
54 process_value_list(t_selexpr_value *values)
55 {
56     t_selexpr_value *val, *pval, *nval;
57
58     /* Count values (if needed) and reverse list */
59     pval = NULL;
60     val  = values;
61     while (val)
62     {
63         nval = val->next;
64         val->next = pval;
65         pval = val;
66         val = nval;
67     }
68     values = pval;
69
70     return values;
71 }
72
73 //! Error handler needed by Bison.
74 static void
75 yyerror(yyscan_t scanner, char const *s)
76 {
77     _gmx_selparser_error(scanner, "%s", s);
78 }
79
80 /*! \name Exception handling macros for actions
81  *
82  * These macros should be used at the beginning and end of each semantic action
83  * that may throw an exception. For robustness, it's best to wrap all actions
84  * that call functions declared outside parser.y should be wrapped.
85  * These macros take care to catch any exceptions, store the exception (or
86  * handle it and allow the parser to continue), and terminate the parser
87  * cleanly if necessary.
88  * The code calling the parser should use
89  * _gmx_sel_lexer_rethrow_exception_if_occurred() to rethrow any exceptions.
90  * \{
91  */
92 //! Starts an action that may throw exceptions.
93 #define BEGIN_ACTION \
94     try {
95 //! Finishes an action that may throw exceptions.
96 #define END_ACTION \
97     } \
98     catch(const std::exception &ex) \
99     { \
100         if (_gmx_selparser_handle_exception(scanner, ex)) \
101             YYERROR; \
102         else \
103             YYABORT; \
104     }
105 //!\}
106
107 /*! \brief
108  * Retrieves a smart pointer from a semantic value.
109  *
110  * \param[in] src  Semantic value to get the pointer from.
111  * \returns   Retrieved smart pointer.
112  *
113  * There should be no statements that may throw exceptions in actions before
114  * this function has been called for all semantic values that have a smart
115  * pointer stored.  Together with set(), this function abstracts away exception
116  * safety issues that arise from the use of a plain pointer for storing the
117  * semantic values.
118  *
119  * Does not throw.
120  */
121 template <typename PointerType> static
122 PointerType get(PointerType *src)
123 {
124     PointerType result;
125     if (src != NULL)
126     {
127         result.swap(*src);
128         delete src;
129     }
130     return move(result);
131 }
132 /*! \brief
133  * Sets a smart pointer to a semantic value.
134  *
135  * \param[out] dest  Semantic value to set (typically $$).
136  * \param[in]  value Pointer to put into the semantic value.
137  * \throws     std::bad_alloc if out of memory.
138  *
139  * This should be the last statement before ::END_ACTION, except for a
140  * possible ::CHECK_SEL.
141  */
142 template <typename PointerType> static
143 void set(PointerType *&dest, PointerType value)
144 {
145     dest = new PointerType(move(value));
146 }
147 /*! \brief
148  * Checks that a valid tree was set.
149  *
150  * Should be called after set() if it was used to set a value where NULL
151  * pointer indicates an error.
152  *
153  * \todo
154  * Get rid of this macro.  It should now be possible to handle all errors using
155  * exceptions.
156  */
157 #define CHECK_SEL(sel) \
158     if (!*(sel)) { \
159         delete sel; \
160         YYERROR; \
161     }
162
163 #endif