From 3e234326f36ffb5f05fa67784d257399a4bdf264 Mon Sep 17 00:00:00 2001 From: Teemu Murtola Date: Wed, 22 Aug 2012 18:32:29 +0300 Subject: [PATCH] C++ classes for selection parser values. Converted t_selexpr_value to gmx::SelectionParserValue and introduced smart pointers and standard containers to manage all memory related to these objects. Related to #655 and #880. Change-Id: Ide2d9db80e89f36c94dccc25085d49959e4115a8 --- src/gromacs/onlinehelp/helpmanager.cpp | 5 + src/gromacs/onlinehelp/helpmanager.h | 4 + src/gromacs/selection/params.cpp | 259 ++++---- src/gromacs/selection/parser.cpp | 795 ++++++++++++------------ src/gromacs/selection/parser.h | 10 +- src/gromacs/selection/parser.y | 158 +++-- src/gromacs/selection/parser_internal.h | 92 +-- src/gromacs/selection/parsetree.cpp | 143 ++--- src/gromacs/selection/parsetree.h | 300 +++++++-- src/gromacs/selection/position.cpp | 2 +- src/gromacs/selection/position.h | 2 +- src/gromacs/selection/sm_same.cpp | 54 +- src/gromacs/selection/tests/selectionoption.cpp | 6 +- 13 files changed, 1012 insertions(+), 818 deletions(-) diff --git a/src/gromacs/onlinehelp/helpmanager.cpp b/src/gromacs/onlinehelp/helpmanager.cpp index 79f0afec70..10032ba8d6 100644 --- a/src/gromacs/onlinehelp/helpmanager.cpp +++ b/src/gromacs/onlinehelp/helpmanager.cpp @@ -146,6 +146,11 @@ void HelpManager::enterTopic(const char *name) impl_->topicStack_.push_back(newTopic); } +void HelpManager::enterTopic(const std::string &name) +{ + enterTopic(name.c_str()); +} + void HelpManager::writeCurrentTopic() const { const HelpTopicInterface &topic = impl_->currentTopic(); diff --git a/src/gromacs/onlinehelp/helpmanager.h b/src/gromacs/onlinehelp/helpmanager.h index fc188100e7..93cdae034c 100644 --- a/src/gromacs/onlinehelp/helpmanager.h +++ b/src/gromacs/onlinehelp/helpmanager.h @@ -39,6 +39,8 @@ #ifndef GMX_ONLINEHELP_HELPMANAGER_H #define GMX_ONLINEHELP_HELPMANAGER_H +#include + #include "../utility/common.h" namespace gmx @@ -79,6 +81,8 @@ class HelpManager * \throws InvalidInputError if topic with \p name is not found. */ void enterTopic(const char *name); + //! \copydoc enterTopic(const char *) + void enterTopic(const std::string &name); /*! \brief * Writes out the help for the currently active topic. diff --git a/src/gromacs/selection/params.cpp b/src/gromacs/selection/params.cpp index 72e2252656..f05c406ed9 100644 --- a/src/gromacs/selection/params.cpp +++ b/src/gromacs/selection/params.cpp @@ -56,9 +56,8 @@ #include "scanner.h" #include "selelem.h" -using std::min; -using std::max; - +using gmx::SelectionParserValue; +using gmx::SelectionParserValueList; using gmx::SelectionParserParameterPointer; using gmx::SelectionParserParameterList; using gmx::SelectionTreeElement; @@ -111,7 +110,7 @@ gmx_ana_selparam_find(const char *name, int nparam, gmx_ana_selparam_t *param) } /*! \brief - * Does a type conversion on a \c t_selexpr_value. + * Does a type conversion on a SelectionParserValue. * * \param[in,out] value Value to convert. * \param[in] type Type to convert to. @@ -119,7 +118,7 @@ gmx_ana_selparam_find(const char *name, int nparam, gmx_ana_selparam_t *param) * \returns 0 on success, a non-zero value on error. */ static int -convert_value(t_selexpr_value *value, e_selvalue_t type, void *scanner) +convert_value(SelectionParserValue *value, e_selvalue_t type, void *scanner) { if (value->type == type || type == NO_VALUE) { @@ -131,14 +130,14 @@ convert_value(t_selexpr_value *value, e_selvalue_t type, void *scanner) * reference positions. */ if (value->type == GROUP_VALUE && type == POS_VALUE) { - value->expr = + SelectionTreeElementPointer expr = _gmx_sel_init_position(value->expr, NULL, scanner); // FIXME: Use exceptions - if (!value->expr) + if (!expr) { return -1; } - value->type = type; + *value = SelectionParserValue::createExpr(expr); return 0; } return -1; @@ -148,24 +147,21 @@ convert_value(t_selexpr_value *value, e_selvalue_t type, void *scanner) /* Integers to floating point are easy */ if (value->type == INT_VALUE && type == REAL_VALUE) { - real r1 = (real)value->u.i.i1; - real r2 = (real)value->u.i.i2; - value->u.r.r1 = r1; - value->u.r.r2 = r2; - value->type = type; + *value = SelectionParserValue::createRealRange(value->u.i.i1, + value->u.i.i2); return 0; } /* Reals that are integer-valued can also be converted */ - if (value->type == REAL_VALUE && type == INT_VALUE - && gmx_within_tol(value->u.r.r1, (int)value->u.r.r1, GMX_REAL_EPS) - && gmx_within_tol(value->u.r.r2, (int)value->u.r.r2, GMX_REAL_EPS)) + if (value->type == REAL_VALUE && type == INT_VALUE) { - int i1 = (int)value->u.r.r1; - int i2 = (int)value->u.r.r2; - value->u.i.i1 = i1; - value->u.i.i2 = i2; - value->type = type; - return 0; + int i1 = static_cast(value->u.r.r1); + int i2 = static_cast(value->u.r.r2); + if (gmx_within_tol(value->u.r.r1, i1, GMX_REAL_EPS) + && gmx_within_tol(value->u.r.r2, i2, GMX_REAL_EPS)) + { + *value = SelectionParserValue::createIntegerRange(i1, i2); + return 0; + } } } return -1; @@ -180,21 +176,17 @@ convert_value(t_selexpr_value *value, e_selvalue_t type, void *scanner) * \returns 0 on success, a non-zero value on error. */ static int -convert_values(t_selexpr_value *values, e_selvalue_t type, void *scanner) +convert_values(SelectionParserValueList *values, e_selvalue_t type, void *scanner) { - t_selexpr_value *value; - int rc, rc1; - - rc = 0; - value = values; - while (value) + int rc = 0; + SelectionParserValueList::iterator value; + for (value = values->begin(); value != values->end(); ++value) { - rc1 = convert_value(value, type, scanner); + int rc1 = convert_value(&*value, type, scanner); if (rc1 != 0 && rc == 0) { rc = rc1; } - value = value->next; } /* FIXME: More informative error messages */ return rc; @@ -297,17 +289,15 @@ cmp_real_range(const void *a, const void *b) /*! \brief * Parses the values for a parameter that takes integer or real ranges. * - * \param[in] nval Number of values in \p values. - * \param[in] values Pointer to the list of values. + * \param[in] values List of values. * \param param Parameter to parse. * \param[in] scanner Scanner data structure. * \returns true if the values were parsed successfully, false otherwise. */ static bool -parse_values_range(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param, - void *scanner) +parse_values_range(const SelectionParserValueList &values, + gmx_ana_selparam_t *param, void *scanner) { - t_selexpr_value *value; int *idata; real *rdata; int i, j, n; @@ -322,15 +312,15 @@ parse_values_range(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param, rdata = NULL; if (param->val.type == INT_VALUE) { - snew(idata, nval*2); + snew(idata, values.size()*2); } else { - snew(rdata, nval*2); + snew(rdata, values.size()*2); } - value = values; i = 0; - while (value) + SelectionParserValueList::const_iterator value; + for (value = values.begin(); value != values.end(); ++value) { if (value->hasExpressionValue()) { @@ -344,47 +334,36 @@ parse_values_range(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param, } if (param->val.type == INT_VALUE) { - /* Make sure the input range is in increasing order */ - if (value->u.i.i1 > value->u.i.i2) - { - int tmp = value->u.i.i1; - value->u.i.i1 = value->u.i.i2; - value->u.i.i2 = tmp; - } + int i1 = std::min(value->u.i.i1, value->u.i.i2); + int i2 = std::max(value->u.i.i1, value->u.i.i2); /* Check if the new range overlaps or extends the previous one */ - if (i > 0 && value->u.i.i1 <= idata[i-1]+1 && value->u.i.i2 >= idata[i-2]-1) + if (i > 0 && i1 <= idata[i-1]+1 && i2 >= idata[i-2]-1) { - idata[i-2] = min(idata[i-2], value->u.i.i1); - idata[i-1] = max(idata[i-1], value->u.i.i2); + idata[i-2] = std::min(idata[i-2], i1); + idata[i-1] = std::max(idata[i-1], i2); } else { - idata[i++] = value->u.i.i1; - idata[i++] = value->u.i.i2; + idata[i++] = i1; + idata[i++] = i2; } } else { - /* Make sure the input range is in increasing order */ - if (value->u.r.r1 > value->u.r.r2) - { - real tmp = value->u.r.r1; - value->u.r.r1 = value->u.r.r2; - value->u.r.r2 = tmp; - } + real r1 = std::min(value->u.r.r1, value->u.r.r2); + real r2 = std::max(value->u.r.r1, value->u.r.r2); /* Check if the new range overlaps or extends the previous one */ - if (i > 0 && value->u.r.r1 <= rdata[i-1] && value->u.r.r2 >= rdata[i-2]) + if (i > 0 && r1 <= rdata[i-1] && r2 >= rdata[i-2]) { - rdata[i-2] = min(rdata[i-2], value->u.r.r1); - rdata[i-1] = max(rdata[i-1], value->u.r.r2); + rdata[i-2] = std::min(rdata[i-2], r1); + rdata[i-1] = std::max(rdata[i-1], r2); } else { - rdata[i++] = value->u.r.r1; - rdata[i++] = value->u.r.r2; + rdata[i++] = r1; + rdata[i++] = r2; } } - value = value->next; } n = i/2; /* Sort the ranges and merge consequent ones */ @@ -476,8 +455,7 @@ parse_values_range(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param, /*! \brief * Parses the values for a parameter that takes a variable number of values. * - * \param[in] nval Number of values in \p values. - * \param[in] values Pointer to the list of values. + * \param[in] values List of values. * \param param Parameter to parse. * \param root Selection element to which child expressions are added. * \param[in] scanner Scanner data structure. @@ -487,26 +465,25 @@ parse_values_range(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param, * is stored, each as a separate value. */ static bool -parse_values_varnum(int nval, t_selexpr_value *values, +parse_values_varnum(const SelectionParserValueList &values, gmx_ana_selparam_t *param, const SelectionTreeElementPointer &root, void *scanner) { - t_selexpr_value *value; int i, j; param->flags &= ~SPAR_DYNAMIC; - /* Update nval if there are integer ranges. */ + /* Compute number of values, considering also integer ranges. */ + size_t valueCount = values.size(); if (param->val.type == INT_VALUE) { - value = values; - while (value) + SelectionParserValueList::const_iterator value; + for (value = values.begin(); value != values.end(); ++value) { if (value->type == INT_VALUE && !value->hasExpressionValue()) { - nval += abs(value->u.i.i2 - value->u.i.i1); + valueCount += abs(value->u.i.i2 - value->u.i.i1); } - value = value->next; } } @@ -522,18 +499,18 @@ parse_values_varnum(int nval, t_selexpr_value *values, /* Reserve appropriate amount of memory */ if (param->val.type == POS_VALUE) { - gmx_ana_pos_reserve(param->val.u.p, nval, 0); - gmx_ana_pos_set_nr(param->val.u.p, nval); + gmx_ana_pos_reserve(param->val.u.p, valueCount, 0); + gmx_ana_pos_set_nr(param->val.u.p, valueCount); gmx_ana_indexmap_init(¶m->val.u.p->m, NULL, NULL, INDEX_UNKNOWN); } else { - _gmx_selvalue_reserve(¶m->val, nval); + _gmx_selvalue_reserve(¶m->val, valueCount); } - value = values; i = 0; - while (value) + SelectionParserValueList::const_iterator value; + for (value = values.begin(); value != values.end(); ++value) { if (value->hasExpressionValue()) { @@ -571,13 +548,14 @@ parse_values_varnum(int nval, t_selexpr_value *values, } param->val.u.r[i++] = value->u.r.r1; break; - case STR_VALUE: param->val.u.s[i++] = strdup(value->u.s); break; + case STR_VALUE: + param->val.u.s[i++] = strdup(value->stringValue().c_str()); + break; case POS_VALUE: copy_rvec(value->u.x, param->val.u.p->x[i++]); break; default: /* Should not be reached */ GMX_ERROR_NORET(gmx::eeInternalError, "Invalid value type"); return false; } - value = value->next; } param->val.nr = i; if (param->nvalptr) @@ -667,28 +645,26 @@ add_child(const SelectionTreeElementPointer &root, gmx_ana_selparam_t *param, /*! \brief * Parses an expression value for a parameter that takes a variable number of values. * - * \param[in] nval Number of values in \p values. - * \param[in] values Pointer to the list of values. + * \param[in] values List of values. * \param param Parameter to parse. * \param root Selection element to which child expressions are added. * \param[in] scanner Scanner data structure. * \returns true if the values were parsed successfully, false otherwise. */ static bool -parse_values_varnum_expr(int nval, t_selexpr_value *values, +parse_values_varnum_expr(const SelectionParserValueList &values, gmx_ana_selparam_t *param, const SelectionTreeElementPointer &root, void *scanner) { - if (nval != 1 || !values->hasExpressionValue()) + if (values.size() != 1 || !values.front().hasExpressionValue()) { GMX_ERROR_NORET(gmx::eeInternalError, "Invalid expression value"); return false; } - t_selexpr_value *value = values; SelectionTreeElementPointer child - = add_child(root, param, value->expr, scanner); + = add_child(root, param, values.front().expr, scanner); if (!child) { return false; @@ -764,9 +740,8 @@ set_expr_value_store(const SelectionTreeElementPointer &sel, /*! \brief * Parses the values for a parameter that takes a constant number of values. - * - * \param[in] nval Number of values in \p values. - * \param[in] values Pointer to the list of values. + * + * \param[in] values List of values. * \param param Parameter to parse. * \param root Selection element to which child expressions are added. * \param[in] scanner Scanner data structure. @@ -776,26 +751,25 @@ set_expr_value_store(const SelectionTreeElementPointer &sel, * is stored, each as a separate value. */ static bool -parse_values_std(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param, +parse_values_std(const SelectionParserValueList &values, + gmx_ana_selparam_t *param, const SelectionTreeElementPointer &root, void *scanner) { - t_selexpr_value *value; int i, j; bool bDynamic; /* Handle atom-valued parameters */ if (param->flags & SPAR_ATOMVAL) { - if (nval > 1) + if (values.size() > 1) { _gmx_selparser_error(scanner, "more than one value not supported"); return false; } - value = values; - if (value->hasExpressionValue()) + if (values.front().hasExpressionValue()) { SelectionTreeElementPointer child - = add_child(root, param, value->expr, scanner); + = add_child(root, param, values.front().expr, scanner); if (!child) { return false; @@ -838,15 +812,14 @@ parse_values_std(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param, param->flags &= ~SPAR_DYNAMIC; } - value = values; i = 0; bDynamic = false; - while (value && i < param->val.nr) + SelectionParserValueList::const_iterator value; + for (value = values.begin(); value != values.end() && i < param->val.nr; ++value) { if (value->type != param->val.type) { _gmx_selparser_error(scanner, "incorrect value skipped"); - value = value->next; continue; } if (value->hasExpressionValue()) @@ -906,7 +879,7 @@ parse_values_std(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param, param->val.u.r[i] = value->u.r.r1; break; case STR_VALUE: - param->val.u.s[i] = strdup(value->u.s); + param->val.u.s[i] = strdup(value->stringValue().c_str()); break; case POS_VALUE: gmx_ana_pos_init_const(¶m->val.u.p[i], value->u.x); @@ -919,11 +892,10 @@ parse_values_std(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param, } } ++i; - value = value->next; } - if (value != NULL) + if (value != values.end()) { - _gmx_selparser_error(scanner, "extra values'"); + _gmx_selparser_error(scanner, "extra values"); return false; } if (i < param->val.nr) @@ -948,14 +920,14 @@ parse_values_std(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param, * Parses the values for a boolean parameter. * * \param[in] name Name by which the parameter was given. - * \param[in] nval Number of values in \p values. - * \param[in] values Pointer to the list of values. + * \param[in] values List of values. * \param param Parameter to parse. * \param[in] scanner Scanner data structure. * \returns true if the values were parsed successfully, false otherwise. */ static bool -parse_values_bool(const std::string &name, int nval, t_selexpr_value *values, +parse_values_bool(const std::string &name, + const SelectionParserValueList &values, gmx_ana_selparam_t *param, void *scanner) { bool bSetNo; @@ -965,7 +937,7 @@ parse_values_bool(const std::string &name, int nval, t_selexpr_value *values, GMX_ERROR_NORET(gmx::eeInternalError, "Invalid boolean parameter"); return false; } - if (nval > 1 || (values && values->type != INT_VALUE)) + if (values.size() > 1 || (!values.empty() && values.front().type != INT_VALUE)) { _gmx_selparser_error(scanner, "parameter takes only a yes/no/on/off/0/1 value"); return false; @@ -978,13 +950,13 @@ parse_values_bool(const std::string &name, int nval, t_selexpr_value *values, { bSetNo = true; } - if (bSetNo && nval > 0) + if (bSetNo && !values.empty()) { _gmx_selparser_error(scanner, "parameter 'no%s' should not have a value", param->name); return false; } - if (values && values->u.i.i1 == 0) + if (!values.empty() && values.front().u.i.i1 == 0) { bSetNo = true; } @@ -996,40 +968,39 @@ parse_values_bool(const std::string &name, int nval, t_selexpr_value *values, /*! \brief * Parses the values for an enumeration parameter. * - * \param[in] nval Number of values in \p values. - * \param[in] values Pointer to the list of values. + * \param[in] values List of values. * \param param Parameter to parse. * \param[in] scanner Scanner data structure. * \returns true if the values were parsed successfully, false otherwise. */ static bool -parse_values_enum(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param, +parse_values_enum(const SelectionParserValueList &values, + gmx_ana_selparam_t *param, void *scanner) { - int i, len, match; - - if (nval != 1) + if (values.size() != 1) { _gmx_selparser_error(scanner, "a single value is required"); return false; } - if (values->type != STR_VALUE || param->val.type != STR_VALUE) + const SelectionParserValue &value = values.front(); + if (value.type != STR_VALUE || param->val.type != STR_VALUE) { GMX_ERROR_NORET(gmx::eeInternalError, "Invalid enum parameter"); return false; } - if (values->hasExpressionValue()) + if (value.hasExpressionValue()) { _gmx_selparser_error(scanner, "expression value for enumerated parameter not supported"); return false; } - len = strlen(values->u.s); - i = 1; - match = 0; + const std::string &svalue = value.stringValue(); + int i = 1; + int match = 0; while (param->val.u.s[i] != NULL) { - if (strncmp(values->u.s, param->val.u.s[i], len) == 0) + if (gmx::startsWith(param->val.u.s[i], svalue)) { /* Check if there is a duplicate match */ if (match > 0) @@ -1056,31 +1027,28 @@ parse_values_enum(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param, * \param[in,out] values First element in the value list to process. */ static void -convert_const_values(t_selexpr_value *values) +convert_const_values(SelectionParserValueList *values) { - t_selexpr_value *val; - - val = values; - while (val) + SelectionParserValueList::iterator value; + for (value = values->begin(); value != values->end(); ++value) { - if (val->hasExpressionValue() && val->expr->v.type != GROUP_VALUE && - val->expr->type == SEL_CONST) + if (value->hasExpressionValue() && value->expr->v.type != GROUP_VALUE && + value->expr->type == SEL_CONST) { - SelectionTreeElementPointer expr = val->expr; - val->expr.reset(); + SelectionTreeElementPointer expr = value->expr; switch (expr->v.type) { case INT_VALUE: - val->u.i.i1 = val->u.i.i2 = expr->v.u.i[0]; + *value = SelectionParserValue::createInteger(expr->v.u.i[0]); break; case REAL_VALUE: - val->u.r.r1 = val->u.r.r2 = expr->v.u.r[0]; + *value = SelectionParserValue::createReal(expr->v.u.r[0]); break; case STR_VALUE: - val->u.s = expr->v.u.s[0]; + *value = SelectionParserValue::createString(expr->v.u.s[0]); break; case POS_VALUE: - copy_rvec(expr->v.u.p->x[0], val->u.x); + *value = SelectionParserValue::createPosition(expr->v.u.p->x[0]); break; default: GMX_ERROR_NORET(gmx::eeInternalError, @@ -1088,7 +1056,6 @@ convert_const_values(t_selexpr_value *values) break; } } - val = val->next; } } @@ -1193,9 +1160,8 @@ _gmx_sel_parse_params(const SelectionParserParameterList &pparams, bOk = false; continue; } - if (oparam->val.type != NO_VALUE && pparam->value == NULL) + if (oparam->val.type != NO_VALUE && pparam->values().empty()) { - GMX_ASSERT(pparam->nval == 0, "Inconsistent values and value count"); _gmx_selparser_error(scanner, "no value provided"); bOk = false; continue; @@ -1208,8 +1174,8 @@ _gmx_sel_parse_params(const SelectionParserParameterList &pparams, } oparam->flags |= SPAR_SET; /* Process the values for the parameter */ - convert_const_values(pparam->value); - if (convert_values(pparam->value, oparam->val.type, scanner) != 0) + convert_const_values(pparam->values_.get()); + if (convert_values(pparam->values_.get(), oparam->val.type, scanner) != 0) { _gmx_selparser_error(scanner, "invalid value"); bOk = false; @@ -1217,30 +1183,31 @@ _gmx_sel_parse_params(const SelectionParserParameterList &pparams, } if (oparam->val.type == NO_VALUE) { - rc = parse_values_bool(pparam->name(), pparam->nval, pparam->value, oparam, scanner); + rc = parse_values_bool(pparam->name(), pparam->values(), oparam, scanner); } else if (oparam->flags & SPAR_RANGES) { - rc = parse_values_range(pparam->nval, pparam->value, oparam, scanner); + rc = parse_values_range(pparam->values(), oparam, scanner); } else if (oparam->flags & SPAR_VARNUM) { - if (pparam->nval == 1 && pparam->value->hasExpressionValue()) + if (pparam->values().size() == 1 + && pparam->values().front().hasExpressionValue()) { - rc = parse_values_varnum_expr(pparam->nval, pparam->value, oparam, root, scanner); + rc = parse_values_varnum_expr(pparam->values(), oparam, root, scanner); } else { - rc = parse_values_varnum(pparam->nval, pparam->value, oparam, root, scanner); + rc = parse_values_varnum(pparam->values(), oparam, root, scanner); } } else if (oparam->flags & SPAR_ENUMVAL) { - rc = parse_values_enum(pparam->nval, pparam->value, oparam, scanner); + rc = parse_values_enum(pparam->values(), oparam, scanner); } else { - rc = parse_values_std(pparam->nval, pparam->value, oparam, root, scanner); + rc = parse_values_std(pparam->values(), oparam, root, scanner); } if (!rc) { diff --git a/src/gromacs/selection/parser.cpp b/src/gromacs/selection/parser.cpp index 2c1857a2ee..d134724879 100644 --- a/src/gromacs/selection/parser.cpp +++ b/src/gromacs/selection/parser.cpp @@ -94,6 +94,9 @@ #include "parser_internal.h" using gmx::scoped_ptr_sfree; +using gmx::SelectionParserValue; +using gmx::SelectionParserValueList; +using gmx::SelectionParserValueListPointer; using gmx::SelectionParserParameter; using gmx::SelectionParserParameterList; using gmx::SelectionParserParameterPointer; @@ -107,7 +110,7 @@ using gmx::SelectionTreeElementPointer; /* Line 268 of yacc.c */ -#line 111 "parser.cpp" +#line 114 "parser.cpp" /* Enabling traces. */ #ifndef YYDEBUG @@ -130,7 +133,7 @@ using gmx::SelectionTreeElementPointer; /* "%code requires" blocks. */ /* Line 288 of yacc.c */ -#line 65 "parser.y" +#line 68 "parser.y" #include "parsetree.h" #include "selelem.h" @@ -138,7 +141,7 @@ using gmx::SelectionTreeElementPointer; /* Line 288 of yacc.c */ -#line 142 "parser.cpp" +#line 145 "parser.cpp" /* Tokens. */ #ifndef YYTOKENTYPE @@ -189,23 +192,23 @@ typedef union YYSTYPE { /* Line 293 of yacc.c */ -#line 70 "parser.y" +#line 73 "parser.y" int i; real r; char *str; struct gmx_ana_selmethod_t *meth; - gmx::SelectionTreeElementPointer *sel; - - struct t_selexpr_value *val; + gmx::SelectionTreeElementPointer *sel; + gmx::SelectionParserValue *val; + gmx::SelectionParserValueListPointer *vlist; gmx::SelectionParserParameterPointer *param; gmx::SelectionParserParameterListPointer *plist; /* Line 293 of yacc.c */ -#line 209 "parser.cpp" +#line 212 "parser.cpp" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -241,7 +244,7 @@ void yypstate_delete (); /* Line 343 of yacc.c */ -#line 245 "parser.cpp" +#line 248 "parser.cpp" #ifdef short # undef short @@ -436,16 +439,16 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 2 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 417 +#define YYLAST 361 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 49 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 26 /* YYNRULES -- Number of rules. */ -#define YYNRULES 90 +#define YYNRULES 89 /* YYNRULES -- Number of states. */ -#define YYNSTATES 149 +#define YYNSTATES 148 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 @@ -500,10 +503,9 @@ static const yytype_uint8 yyprhs[] = 74, 77, 81, 85, 89, 93, 96, 99, 101, 103, 106, 110, 114, 118, 120, 122, 125, 129, 133, 137, 141, 145, 148, 152, 156, 158, 161, 169, 173, 176, - 180, 182, 184, 186, 188, 191, 192, 195, 198, 199, - 201, 205, 207, 210, 214, 216, 220, 222, 225, 229, - 231, 233, 235, 237, 239, 241, 243, 245, 247, 251, - 255 + 180, 182, 184, 186, 188, 191, 192, 195, 198, 200, + 204, 205, 208, 212, 214, 218, 220, 223, 227, 229, + 231, 233, 235, 237, 239, 241, 243, 245, 249, 253 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ @@ -528,28 +530,27 @@ static const yytype_int8 yyrhs[] = -1, 44, 58, 45, 58, 45, 58, 46, -1, 42, 64, 43, -1, 22, 65, -1, 18, 27, 60, -1, 14, -1, 13, -1, 15, -1, 66, -1, 66, 26, - -1, -1, 66, 67, -1, 25, 68, -1, -1, 69, - -1, 47, 69, 48, -1, 72, -1, 69, 72, -1, - 69, 45, 72, -1, 71, -1, 47, 71, 48, -1, - 73, -1, 71, 73, -1, 71, 45, 73, -1, 60, - -1, 64, -1, 62, -1, 63, -1, 74, -1, 56, - -1, 57, -1, 59, -1, 74, -1, 56, 12, 56, - -1, 56, 12, 57, -1, 57, 12, 58, -1 + -1, -1, 66, 67, -1, 25, 68, -1, 69, -1, + 47, 69, 48, -1, -1, 69, 72, -1, 69, 45, + 72, -1, 71, -1, 47, 71, 48, -1, 73, -1, + 71, 73, -1, 71, 45, 73, -1, 60, -1, 64, + -1, 62, -1, 63, -1, 74, -1, 56, -1, 57, + -1, 59, -1, 74, -1, 56, 12, 56, -1, 56, + 12, 57, -1, 57, 12, 58, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 187, 187, 188, 199, 200, 222, 228, 229, 241, - 254, 260, 267, 274, 281, 292, 300, 301, 311, 312, - 319, 320, 334, 335, 339, 340, 343, 344, 347, 348, - 356, 367, 378, 389, 393, 403, 411, 421, 422, 426, - 434, 442, 453, 468, 479, 493, 501, 512, 518, 524, - 530, 536, 542, 548, 555, 566, 581, 590, 594, 604, - 618, 626, 634, 647, 649, 655, 660, 671, 680, 681, - 682, 686, 687, 689, 694, 695, 699, 700, 702, 706, - 712, 718, 724, 730, 734, 741, 748, 755, 759, 766, - 773 + 0, 191, 191, 196, 207, 208, 230, 236, 242, 254, + 267, 273, 280, 287, 294, 305, 314, 319, 330, 331, + 338, 339, 353, 354, 358, 359, 362, 363, 366, 367, + 375, 386, 397, 408, 412, 423, 431, 441, 442, 446, + 454, 462, 473, 488, 499, 513, 521, 532, 538, 544, + 550, 556, 562, 568, 575, 586, 601, 610, 614, 624, + 638, 646, 654, 667, 669, 675, 680, 691, 700, 701, + 706, 711, 719, 730, 731, 735, 741, 749, 759, 765, + 771, 777, 783, 787, 793, 799, 806, 810, 816, 822 }; #endif @@ -598,9 +599,8 @@ static const yytype_uint8 yyr1[] = 60, 60, 60, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 64, 64, 64, 64, 60, 62, 64, 65, 65, 66, 66, 67, 68, 68, - 68, 69, 69, 69, 70, 70, 71, 71, 71, 72, - 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, - 74 + 69, 69, 69, 70, 70, 71, 71, 71, 72, 72, + 72, 72, 72, 73, 73, 73, 73, 74, 74, 74 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -612,10 +612,9 @@ static const yytype_uint8 yyr2[] = 2, 3, 3, 3, 3, 2, 2, 1, 1, 2, 3, 3, 3, 1, 1, 2, 3, 3, 3, 3, 3, 2, 3, 3, 1, 2, 7, 3, 2, 3, - 1, 1, 1, 1, 2, 0, 2, 2, 0, 1, - 3, 1, 2, 3, 1, 3, 1, 2, 3, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, - 3 + 1, 1, 1, 1, 2, 0, 2, 2, 1, 3, + 0, 2, 3, 1, 3, 1, 2, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 3, 3 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. @@ -630,52 +629,52 @@ static const yytype_uint8 yydefact[] = 0, 30, 0, 0, 51, 0, 19, 0, 18, 22, 24, 0, 26, 27, 0, 4, 65, 11, 0, 0, 45, 0, 39, 65, 65, 0, 0, 0, 0, 0, - 0, 17, 0, 12, 13, 14, 59, 68, 64, 66, + 0, 17, 0, 12, 13, 14, 59, 70, 64, 66, 0, 0, 45, 20, 33, 53, 57, 23, 25, 0, - 21, 32, 31, 0, 84, 85, 86, 41, 74, 76, - 87, 40, 46, 42, 34, 47, 48, 49, 50, 52, - 0, 43, 44, 0, 0, 0, 0, 54, 79, 0, - 81, 82, 80, 67, 69, 71, 83, 0, 0, 0, - 0, 0, 77, 43, 44, 0, 55, 0, 72, 0, - 75, 88, 89, 90, 78, 70, 73, 0, 56 + 21, 32, 31, 0, 83, 84, 85, 41, 73, 75, + 86, 40, 46, 42, 34, 47, 48, 49, 50, 52, + 0, 70, 67, 68, 0, 0, 0, 0, 0, 76, + 0, 43, 44, 0, 0, 0, 0, 54, 78, 0, + 80, 81, 79, 71, 82, 0, 74, 87, 88, 89, + 77, 69, 43, 44, 72, 55, 0, 56 }; /* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = +static const yytype_int16 yydefgoto[] = { -1, 1, 20, 21, 22, 30, 23, 94, 95, 54, - 96, 118, 26, 27, 121, 122, 36, 37, 79, 123, - 124, 101, 98, 125, 99, 100 + 96, 128, 26, 27, 131, 132, 36, 37, 79, 112, + 113, 101, 98, 133, 99, 100 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -72 +#define YYPACT_NINF -83 static const yytype_int16 yypact[] = { - -72, 157, -72, 4, -72, 8, -72, -72, -21, 116, - -72, -72, -72, 20, -72, -72, 359, 243, 320, 6, - -72, 25, -72, 14, 320, 31, 286, 258, -72, -72, - 76, 345, -72, -72, -72, 359, -72, 52, -72, -72, - 359, -72, 243, 18, 46, -20, -22, 75, 56, -72, - -72, 84, -72, -72, 50, -72, -72, 14, 359, 359, - -2, 176, -72, -72, -72, 243, 243, 243, 243, 243, - 243, -72, 345, 31, 258, -72, 31, 224, -72, -72, - -22, 361, -72, -72, -72, -72, -72, -72, -72, 6, - -72, 69, -72, 23, 108, 117, -72, -72, 210, -72, - -72, -72, -72, -72, 114, 68, 68, 46, 46, 46, - 56, 118, 123, 375, 306, 108, 117, -72, 31, 386, - 114, -72, -72, -72, 266, -72, -72, 83, 199, 6, - 6, 23, -72, 131, 132, 180, 176, 306, -72, 6, - -72, -72, -72, -72, -72, -72, -72, 99, -72 + -83, 141, -83, -5, -83, 13, -83, -83, -23, 118, + -83, -83, -83, 4, -83, -83, 300, 316, 261, 15, + -83, 36, -83, 40, 261, 8, 184, 198, -83, -83, + 70, 286, -83, -83, -83, 300, -83, 44, -83, -83, + 300, -83, 316, 29, 62, -19, 77, 159, 54, -83, + -83, 131, -83, -83, 38, -83, -83, 40, 300, 300, + 49, 58, -83, -83, -83, 316, 316, 316, 316, 316, + 316, -83, 286, 8, 198, -83, 8, 63, -83, -83, + 77, 310, -83, -83, -83, -83, -83, -83, -83, 15, + -83, 89, -83, 7, 127, 134, -83, -83, 122, -83, + -83, -83, -83, -83, 79, 55, 55, 62, 62, 62, + 54, -83, -83, 207, 113, 3, 15, 15, 7, -83, + 164, 150, 152, 319, 247, 127, 134, -83, 8, 227, + 79, -83, -83, -83, -83, 15, -83, -83, -83, -83, + -83, -83, 154, 156, -83, 58, 88, -83 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -72, -72, -72, -72, -72, -72, -7, 3, 17, -46, - -1, 24, 2, -16, -72, 15, 10, -72, -72, -72, - 41, 100, 66, -35, -71, -49 + -83, -83, -83, -83, -83, -83, 10, -18, -13, -82, + -1, 1, 20, 12, -83, 2, 97, -83, -83, -83, + 69, 109, 91, 57, -71, -52 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -684,100 +683,90 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -26 static const yytype_int16 yytable[] = { - 24, 44, 47, 56, 49, 50, 7, 33, 34, 58, - 59, 45, 49, 50, 29, 74, 28, 57, -8, 43, - 31, 84, 52, 83, 47, 25, 81, 132, 126, 49, - 50, 7, 33, 48, 82, 55, 53, 56, 63, 28, - 41, 51, 46, 127, 43, 93, 75, 35, 25, 104, - 105, 106, 107, 108, 109, 73, 47, 132, 51, 76, - 144, 120, 58, 59, 80, 126, 90, 43, 43, 43, - 43, 43, 43, 102, 103, 126, 117, 77, 78, 119, - 115, 71, 91, 92, 143, 70, 126, 110, 126, 138, - 87, 88, 52, 147, 116, 89, 80, 44, 120, 86, - 138, 59, 146, 65, 68, 69, 53, 70, 120, 66, - 67, 68, 69, 117, 70, 43, 119, 115, 85, 120, - 129, 120, 32, 117, 7, 33, 119, 115, 139, 130, - -22, 116, 141, 52, 117, -24, 117, 119, 115, 119, - 115, 116, 52, -23, -25, 148, 142, 53, 66, 67, - 68, 69, 116, 70, 116, 135, 53, 2, 3, 128, - 97, 4, 0, 5, 6, 7, 8, -6, 9, 0, - 10, 11, 12, 0, 0, 13, 0, 0, 0, 14, - 0, 15, 49, 50, 7, 33, 111, 112, 7, 33, - 16, 9, 17, 10, 11, 12, 0, 0, 13, 18, - 0, 19, 14, 0, 15, 49, 50, 7, 33, 0, - 0, 51, 0, 16, 0, 113, 49, 50, 7, 33, - 0, 0, 72, 93, 19, 137, 0, 0, 145, 0, - 111, 112, 7, 33, 51, 9, 0, 10, 11, 12, - 0, 0, 13, 0, 131, 51, 14, 140, 15, 38, - 6, 0, 0, 0, 0, 131, 10, 16, 0, 113, - 0, 39, 0, 0, 0, 0, 72, 15, 19, 0, - 0, 114, 111, 112, 7, 33, 0, 9, 17, 10, - 11, 12, 0, 0, 13, 42, 65, 0, 14, 0, - 15, 0, 66, 67, 68, 69, 0, 70, 0, 16, - 0, 113, 60, 61, 0, 62, 63, 64, 72, 0, - 19, 137, 111, 112, 7, 33, 0, 9, 0, 10, - 11, 12, 0, 0, 13, 0, 38, 6, 14, 0, - 15, 9, 0, 10, 11, 12, 0, 0, 13, 16, - 0, 113, 14, 0, 15, 0, 0, 0, 72, 0, - 19, 38, 6, 16, 0, 17, 9, 0, 10, 11, - 12, 0, 18, 13, 19, 38, 6, 14, 0, 15, - 9, 0, 10, 11, 0, 0, 0, 39, 16, 0, - 17, 133, 134, 15, 0, 0, 0, 72, 10, 19, - 0, 0, 16, 39, 17, 66, 67, 68, 69, 15, - 70, 40, 60, 136, 85, 62, 63, 64, 0, 0, - 17, 0, 0, 0, 0, 0, 0, 42 + 24, 52, 25, 28, 56, 29, 53, 114, 34, 49, + 50, 7, 33, 49, 50, 7, 33, 41, 31, 46, + 48, 49, 50, -8, 83, 25, 28, 119, 45, 44, + 47, 35, 73, 75, 57, 139, 76, 43, 51, 58, + 59, 80, 51, 74, 119, 82, 55, 140, 118, 63, + 51, 136, 47, 146, 81, 49, 50, 7, 33, 91, + 92, 134, 43, 56, 49, 50, 7, 33, 134, 77, + 78, 52, 134, 80, 110, 71, 53, 104, 105, 106, + 107, 108, 109, 89, 47, 43, 43, 43, 43, 43, + 43, 68, 69, 51, 70, 125, 93, 86, 137, 52, + 126, 70, 125, 138, 53, 93, 125, 126, 58, 59, + 111, 126, 127, 66, 67, 68, 69, 52, 70, 127, + 84, 59, 53, 127, 32, 130, 7, 33, 49, 50, + 7, 33, 130, 129, 147, 44, 130, 87, 88, 116, + 129, 2, 3, 43, 129, 4, 117, 5, 6, 7, + 8, -6, 9, 90, 10, 11, 12, 51, 135, 13, + 102, 103, -22, 14, -24, 15, -23, 118, -25, 97, + 121, 122, 7, 33, 16, 9, 17, 10, 11, 12, + 120, 144, 13, 18, 115, 19, 14, 65, 15, 0, + 0, 0, 0, 66, 67, 68, 69, 16, 70, 123, + 60, 61, 85, 62, 63, 64, 72, 0, 19, 124, + 0, 0, 141, 121, 122, 7, 33, 0, 9, 0, + 10, 11, 12, 0, 0, 13, 65, 0, 0, 14, + 0, 15, 66, 67, 68, 69, 0, 70, 0, 0, + 16, 0, 123, 60, 145, 0, 62, 63, 64, 72, + 0, 19, 124, 121, 122, 7, 33, 0, 9, 0, + 10, 11, 12, 0, 0, 13, 0, 38, 6, 14, + 0, 15, 9, 0, 10, 11, 12, 0, 0, 13, + 16, 0, 123, 14, 0, 15, 0, 0, 0, 72, + 0, 19, 38, 6, 16, 0, 17, 9, 0, 10, + 11, 12, 0, 18, 13, 19, 38, 6, 14, 0, + 15, 9, 0, 10, 11, 0, 0, 0, 39, 16, + 0, 17, 38, 6, 15, 142, 143, 0, 72, 10, + 19, 0, 10, 16, 39, 17, 0, 39, 0, 0, + 15, 0, 40, 15, 66, 67, 68, 69, 0, 70, + 0, 17, 0, 85, 17, 0, 0, 0, 42, 0, + 0, 42 }; #define yypact_value_is_default(yystate) \ - ((yystate) == (-72)) + ((yystate) == (-83)) #define yytable_value_is_error(yytable_value) \ YYID (0) static const yytype_int16 yycheck[] = { - 1, 17, 18, 23, 6, 7, 8, 9, 9, 31, - 32, 18, 6, 7, 10, 31, 1, 24, 10, 17, - 41, 43, 19, 43, 40, 1, 42, 98, 77, 6, - 7, 8, 9, 18, 16, 10, 19, 23, 20, 24, - 16, 35, 18, 89, 42, 47, 31, 27, 24, 65, - 66, 67, 68, 69, 70, 31, 72, 128, 35, 35, - 131, 77, 31, 32, 40, 114, 56, 65, 66, 67, - 68, 69, 70, 63, 64, 124, 77, 25, 26, 77, - 77, 5, 58, 59, 130, 39, 135, 72, 137, 124, - 6, 7, 89, 139, 77, 45, 72, 113, 114, 43, - 135, 32, 137, 28, 36, 37, 89, 39, 124, 34, - 35, 36, 37, 114, 39, 113, 114, 114, 43, 135, - 12, 137, 6, 124, 8, 9, 124, 124, 45, 12, - 12, 114, 129, 130, 135, 12, 137, 135, 135, 137, - 137, 124, 139, 12, 12, 46, 129, 130, 34, 35, - 36, 37, 135, 39, 137, 114, 139, 0, 1, 93, - 60, 4, -1, 6, 7, 8, 9, 10, 11, -1, - 13, 14, 15, -1, -1, 18, -1, -1, -1, 22, - -1, 24, 6, 7, 8, 9, 6, 7, 8, 9, - 33, 11, 35, 13, 14, 15, -1, -1, 18, 42, - -1, 44, 22, -1, 24, 6, 7, 8, 9, -1, - -1, 35, -1, 33, -1, 35, 6, 7, 8, 9, - -1, -1, 42, 47, 44, 45, -1, -1, 48, -1, - 6, 7, 8, 9, 35, 11, -1, 13, 14, 15, - -1, -1, 18, -1, 45, 35, 22, 48, 24, 6, - 7, -1, -1, -1, -1, 45, 13, 33, -1, 35, - -1, 18, -1, -1, -1, -1, 42, 24, 44, -1, - -1, 47, 6, 7, 8, 9, -1, 11, 35, 13, - 14, 15, -1, -1, 18, 42, 28, -1, 22, -1, - 24, -1, 34, 35, 36, 37, -1, 39, -1, 33, - -1, 35, 16, 17, -1, 19, 20, 21, 42, -1, - 44, 45, 6, 7, 8, 9, -1, 11, -1, 13, - 14, 15, -1, -1, 18, -1, 6, 7, 22, -1, - 24, 11, -1, 13, 14, 15, -1, -1, 18, 33, - -1, 35, 22, -1, 24, -1, -1, -1, 42, -1, - 44, 6, 7, 33, -1, 35, 11, -1, 13, 14, - 15, -1, 42, 18, 44, 6, 7, 22, -1, 24, - 11, -1, 13, 14, -1, -1, -1, 18, 33, -1, - 35, 6, 7, 24, -1, -1, -1, 42, 13, 44, - -1, -1, 33, 18, 35, 34, 35, 36, 37, 24, - 39, 42, 16, 17, 43, 19, 20, 21, -1, -1, - 35, -1, -1, -1, -1, -1, -1, 42 + 1, 19, 1, 1, 23, 10, 19, 89, 9, 6, + 7, 8, 9, 6, 7, 8, 9, 16, 41, 18, + 18, 6, 7, 10, 43, 24, 24, 98, 18, 17, + 18, 27, 31, 31, 24, 117, 35, 17, 35, 31, + 32, 40, 35, 31, 115, 16, 10, 118, 45, 20, + 35, 48, 40, 135, 42, 6, 7, 8, 9, 58, + 59, 113, 42, 23, 6, 7, 8, 9, 120, 25, + 26, 89, 124, 72, 72, 5, 89, 65, 66, 67, + 68, 69, 70, 45, 72, 65, 66, 67, 68, 69, + 70, 36, 37, 35, 39, 113, 47, 43, 116, 117, + 113, 39, 120, 116, 117, 47, 124, 120, 31, 32, + 47, 124, 113, 34, 35, 36, 37, 135, 39, 120, + 43, 32, 135, 124, 6, 113, 8, 9, 6, 7, + 8, 9, 120, 113, 46, 123, 124, 6, 7, 12, + 120, 0, 1, 123, 124, 4, 12, 6, 7, 8, + 9, 10, 11, 56, 13, 14, 15, 35, 45, 18, + 63, 64, 12, 22, 12, 24, 12, 45, 12, 60, + 6, 7, 8, 9, 33, 11, 35, 13, 14, 15, + 111, 124, 18, 42, 93, 44, 22, 28, 24, -1, + -1, -1, -1, 34, 35, 36, 37, 33, 39, 35, + 16, 17, 43, 19, 20, 21, 42, -1, 44, 45, + -1, -1, 48, 6, 7, 8, 9, -1, 11, -1, + 13, 14, 15, -1, -1, 18, 28, -1, -1, 22, + -1, 24, 34, 35, 36, 37, -1, 39, -1, -1, + 33, -1, 35, 16, 17, -1, 19, 20, 21, 42, + -1, 44, 45, 6, 7, 8, 9, -1, 11, -1, + 13, 14, 15, -1, -1, 18, -1, 6, 7, 22, + -1, 24, 11, -1, 13, 14, 15, -1, -1, 18, + 33, -1, 35, 22, -1, 24, -1, -1, -1, 42, + -1, 44, 6, 7, 33, -1, 35, 11, -1, 13, + 14, 15, -1, 42, 18, 44, 6, 7, 22, -1, + 24, 11, -1, 13, 14, -1, -1, -1, 18, 33, + -1, 35, 6, 7, 24, 6, 7, -1, 42, 13, + 44, -1, 13, 33, 18, 35, -1, 18, -1, -1, + 24, -1, 42, 24, 34, 35, 36, 37, -1, 39, + -1, 35, -1, 43, 35, -1, -1, -1, 42, -1, + -1, 42 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -795,10 +784,10 @@ static const yytype_uint8 yystos[] = 60, 62, 16, 43, 43, 43, 43, 6, 7, 45, 65, 60, 60, 47, 56, 57, 59, 70, 71, 73, 74, 70, 65, 65, 62, 62, 62, 62, 62, 62, - 64, 6, 7, 35, 47, 56, 57, 59, 60, 61, - 62, 63, 64, 68, 69, 72, 74, 58, 71, 12, - 12, 45, 73, 6, 7, 69, 17, 45, 72, 45, - 48, 56, 57, 58, 73, 48, 72, 58, 46 + 64, 47, 68, 69, 58, 71, 12, 12, 45, 73, + 69, 6, 7, 35, 45, 56, 57, 59, 60, 61, + 62, 63, 64, 72, 74, 45, 48, 56, 57, 58, + 73, 48, 6, 7, 72, 17, 58, 46 }; #define yyerrok (yyerrstatus = 0) @@ -1343,245 +1332,245 @@ yydestruct (yymsg, yytype, yyvaluep, scanner) case 5: /* "HELP_TOPIC" */ /* Line 1391 of yacc.c */ -#line 167 "parser.y" - { free((yyvaluep->str)); }; +#line 170 "parser.y" + { free((yyvaluep->str)); }; /* Line 1391 of yacc.c */ -#line 1351 "parser.cpp" +#line 1340 "parser.cpp" break; case 8: /* "STR" */ /* Line 1391 of yacc.c */ -#line 167 "parser.y" - { free((yyvaluep->str)); }; +#line 170 "parser.y" + { free((yyvaluep->str)); }; /* Line 1391 of yacc.c */ -#line 1360 "parser.cpp" +#line 1349 "parser.cpp" break; case 9: /* "IDENTIFIER" */ /* Line 1391 of yacc.c */ -#line 167 "parser.y" - { free((yyvaluep->str)); }; +#line 170 "parser.y" + { free((yyvaluep->str)); }; /* Line 1391 of yacc.c */ -#line 1369 "parser.cpp" +#line 1358 "parser.cpp" break; case 18: /* "KEYWORD_POS" */ /* Line 1391 of yacc.c */ -#line 167 "parser.y" - { free((yyvaluep->str)); }; +#line 170 "parser.y" + { free((yyvaluep->str)); }; /* Line 1391 of yacc.c */ -#line 1378 "parser.cpp" +#line 1367 "parser.cpp" break; case 25: /* "PARAM" */ /* Line 1391 of yacc.c */ -#line 168 "parser.y" - { if((yyvaluep->str)) free((yyvaluep->str)); }; +#line 171 "parser.y" + { if((yyvaluep->str)) free((yyvaluep->str)); }; /* Line 1391 of yacc.c */ -#line 1387 "parser.cpp" +#line 1376 "parser.cpp" break; case 28: /* "CMP_OP" */ /* Line 1391 of yacc.c */ -#line 167 "parser.y" - { free((yyvaluep->str)); }; +#line 170 "parser.y" + { free((yyvaluep->str)); }; /* Line 1391 of yacc.c */ -#line 1396 "parser.cpp" +#line 1385 "parser.cpp" break; case 50: /* "commands" */ /* Line 1391 of yacc.c */ -#line 169 "parser.y" - { delete (yyvaluep->sel); }; +#line 172 "parser.y" + { delete (yyvaluep->sel); }; /* Line 1391 of yacc.c */ -#line 1405 "parser.cpp" +#line 1394 "parser.cpp" break; case 51: /* "command" */ /* Line 1391 of yacc.c */ -#line 169 "parser.y" - { delete (yyvaluep->sel); }; +#line 172 "parser.y" + { delete (yyvaluep->sel); }; /* Line 1391 of yacc.c */ -#line 1414 "parser.cpp" +#line 1403 "parser.cpp" break; case 52: /* "cmd_plain" */ /* Line 1391 of yacc.c */ -#line 169 "parser.y" - { delete (yyvaluep->sel); }; +#line 172 "parser.y" + { delete (yyvaluep->sel); }; /* Line 1391 of yacc.c */ -#line 1423 "parser.cpp" +#line 1412 "parser.cpp" break; case 54: /* "help_topic" */ /* Line 1391 of yacc.c */ -#line 174 "parser.y" - { _gmx_selexpr_free_values((yyvaluep->val)); }; +#line 177 "parser.y" + { delete (yyvaluep->vlist); }; /* Line 1391 of yacc.c */ -#line 1432 "parser.cpp" +#line 1421 "parser.cpp" break; case 55: /* "selection" */ /* Line 1391 of yacc.c */ -#line 169 "parser.y" - { delete (yyvaluep->sel); }; +#line 172 "parser.y" + { delete (yyvaluep->sel); }; /* Line 1391 of yacc.c */ -#line 1441 "parser.cpp" +#line 1430 "parser.cpp" break; case 59: /* "string" */ /* Line 1391 of yacc.c */ -#line 167 "parser.y" - { free((yyvaluep->str)); }; +#line 170 "parser.y" + { free((yyvaluep->str)); }; /* Line 1391 of yacc.c */ -#line 1450 "parser.cpp" +#line 1439 "parser.cpp" break; case 60: /* "sel_expr" */ /* Line 1391 of yacc.c */ -#line 170 "parser.y" - { delete (yyvaluep->sel); }; +#line 173 "parser.y" + { delete (yyvaluep->sel); }; /* Line 1391 of yacc.c */ -#line 1459 "parser.cpp" +#line 1448 "parser.cpp" break; case 61: /* "pos_mod" */ /* Line 1391 of yacc.c */ -#line 168 "parser.y" - { if((yyvaluep->str)) free((yyvaluep->str)); }; +#line 171 "parser.y" + { if((yyvaluep->str)) free((yyvaluep->str)); }; /* Line 1391 of yacc.c */ -#line 1468 "parser.cpp" +#line 1457 "parser.cpp" break; case 62: /* "num_expr" */ /* Line 1391 of yacc.c */ -#line 170 "parser.y" - { delete (yyvaluep->sel); }; +#line 173 "parser.y" + { delete (yyvaluep->sel); }; /* Line 1391 of yacc.c */ -#line 1477 "parser.cpp" +#line 1466 "parser.cpp" break; case 63: /* "str_expr" */ /* Line 1391 of yacc.c */ -#line 170 "parser.y" - { delete (yyvaluep->sel); }; +#line 173 "parser.y" + { delete (yyvaluep->sel); }; /* Line 1391 of yacc.c */ -#line 1486 "parser.cpp" +#line 1475 "parser.cpp" break; case 64: /* "pos_expr" */ /* Line 1391 of yacc.c */ -#line 170 "parser.y" - { delete (yyvaluep->sel); }; +#line 173 "parser.y" + { delete (yyvaluep->sel); }; /* Line 1391 of yacc.c */ -#line 1495 "parser.cpp" +#line 1484 "parser.cpp" break; case 65: /* "method_params" */ /* Line 1391 of yacc.c */ -#line 171 "parser.y" - { delete (yyvaluep->plist); }; +#line 174 "parser.y" + { delete (yyvaluep->plist); }; /* Line 1391 of yacc.c */ -#line 1504 "parser.cpp" +#line 1493 "parser.cpp" break; case 66: /* "method_param_list" */ /* Line 1391 of yacc.c */ -#line 171 "parser.y" - { delete (yyvaluep->plist); }; +#line 174 "parser.y" + { delete (yyvaluep->plist); }; /* Line 1391 of yacc.c */ -#line 1513 "parser.cpp" +#line 1502 "parser.cpp" break; case 67: /* "method_param" */ /* Line 1391 of yacc.c */ -#line 171 "parser.y" - { delete (yyvaluep->param); }; +#line 174 "parser.y" + { delete (yyvaluep->param); }; /* Line 1391 of yacc.c */ -#line 1522 "parser.cpp" +#line 1511 "parser.cpp" break; case 68: /* "value_list" */ /* Line 1391 of yacc.c */ -#line 172 "parser.y" - { _gmx_selexpr_free_values((yyvaluep->val)); }; +#line 175 "parser.y" + { delete (yyvaluep->vlist); }; /* Line 1391 of yacc.c */ -#line 1531 "parser.cpp" +#line 1520 "parser.cpp" break; case 69: /* "value_list_contents" */ /* Line 1391 of yacc.c */ -#line 172 "parser.y" - { _gmx_selexpr_free_values((yyvaluep->val)); }; +#line 175 "parser.y" + { delete (yyvaluep->vlist); }; /* Line 1391 of yacc.c */ -#line 1540 "parser.cpp" +#line 1529 "parser.cpp" break; case 70: /* "basic_value_list" */ /* Line 1391 of yacc.c */ -#line 173 "parser.y" - { _gmx_selexpr_free_values((yyvaluep->val)); }; +#line 175 "parser.y" + { delete (yyvaluep->vlist); }; /* Line 1391 of yacc.c */ -#line 1549 "parser.cpp" +#line 1538 "parser.cpp" break; case 71: /* "basic_value_list_contents" */ /* Line 1391 of yacc.c */ -#line 173 "parser.y" - { _gmx_selexpr_free_values((yyvaluep->val)); }; +#line 175 "parser.y" + { delete (yyvaluep->vlist); }; /* Line 1391 of yacc.c */ -#line 1558 "parser.cpp" +#line 1547 "parser.cpp" break; case 72: /* "value_item" */ /* Line 1391 of yacc.c */ -#line 172 "parser.y" - { _gmx_selexpr_free_values((yyvaluep->val)); }; +#line 176 "parser.y" + { delete (yyvaluep->val); }; /* Line 1391 of yacc.c */ -#line 1567 "parser.cpp" +#line 1556 "parser.cpp" break; case 73: /* "basic_value_item" */ /* Line 1391 of yacc.c */ -#line 173 "parser.y" - { _gmx_selexpr_free_values((yyvaluep->val)); }; +#line 176 "parser.y" + { delete (yyvaluep->val); }; /* Line 1391 of yacc.c */ -#line 1576 "parser.cpp" +#line 1565 "parser.cpp" break; case 74: /* "value_item_range" */ /* Line 1391 of yacc.c */ -#line 172 "parser.y" - { _gmx_selexpr_free_values((yyvaluep->val)); }; +#line 176 "parser.y" + { delete (yyvaluep->val); }; /* Line 1391 of yacc.c */ -#line 1585 "parser.cpp" +#line 1574 "parser.cpp" break; default: @@ -1930,14 +1919,18 @@ yyreduce: case 2: /* Line 1806 of yacc.c */ -#line 187 "parser.y" - { (yyval.sel) = NULL; } +#line 191 "parser.y" + { + BEGIN_ACTION; + set_empty((yyval.sel)); + END_ACTION; + } break; case 3: /* Line 1806 of yacc.c */ -#line 189 "parser.y" +#line 197 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_append_selection(get((yyvsp[(2) - (2)].sel)), get((yyvsp[(1) - (2)].sel)), scanner)); @@ -1950,17 +1943,16 @@ yyreduce: case 4: /* Line 1806 of yacc.c */ -#line 199 "parser.y" +#line 207 "parser.y" { (yyval.sel) = (yyvsp[(1) - (2)].sel); } break; case 5: /* Line 1806 of yacc.c */ -#line 201 "parser.y" +#line 209 "parser.y" { BEGIN_ACTION; - (yyval.sel) = NULL; _gmx_selparser_error(scanner, "invalid selection '%s'", _gmx_sel_lexer_pselstr(scanner)); _gmx_sel_lexer_clear_method_stack(scanner); @@ -1973,6 +1965,7 @@ yyreduce: { YYABORT; } + set_empty((yyval.sel)); END_ACTION; } break; @@ -1980,11 +1973,11 @@ yyreduce: case 6: /* Line 1806 of yacc.c */ -#line 222 "parser.y" +#line 230 "parser.y" { BEGIN_ACTION; - (yyval.sel) = NULL; _gmx_sel_handle_empty_cmd(scanner); + set_empty((yyval.sel)); END_ACTION; } break; @@ -1992,14 +1985,18 @@ yyreduce: case 7: /* Line 1806 of yacc.c */ -#line 228 "parser.y" - { (yyval.sel) = NULL; } +#line 237 "parser.y" + { + BEGIN_ACTION; + set_empty((yyval.sel)); + END_ACTION; + } break; case 8: /* Line 1806 of yacc.c */ -#line 230 "parser.y" +#line 243 "parser.y" { BEGIN_ACTION; SelectionTreeElementPointer s @@ -2016,7 +2013,7 @@ yyreduce: case 9: /* Line 1806 of yacc.c */ -#line 242 "parser.y" +#line 255 "parser.y" { BEGIN_ACTION; scoped_ptr_sfree nameGuard((yyvsp[(1) - (1)].str)); @@ -2034,7 +2031,7 @@ yyreduce: case 10: /* Line 1806 of yacc.c */ -#line 255 "parser.y" +#line 268 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_init_selection(NULL, get((yyvsp[(1) - (1)].sel)), scanner)); @@ -2045,7 +2042,7 @@ yyreduce: case 11: /* Line 1806 of yacc.c */ -#line 261 "parser.y" +#line 274 "parser.y" { BEGIN_ACTION; scoped_ptr_sfree nameGuard((yyvsp[(1) - (2)].str)); @@ -2057,7 +2054,7 @@ yyreduce: case 12: /* Line 1806 of yacc.c */ -#line 268 "parser.y" +#line 281 "parser.y" { BEGIN_ACTION; scoped_ptr_sfree nameGuard((yyvsp[(1) - (3)].str)); @@ -2069,7 +2066,7 @@ yyreduce: case 13: /* Line 1806 of yacc.c */ -#line 275 "parser.y" +#line 288 "parser.y" { BEGIN_ACTION; scoped_ptr_sfree nameGuard((yyvsp[(1) - (3)].str)); @@ -2081,7 +2078,7 @@ yyreduce: case 14: /* Line 1806 of yacc.c */ -#line 282 "parser.y" +#line 295 "parser.y" { BEGIN_ACTION; scoped_ptr_sfree nameGuard((yyvsp[(1) - (3)].str)); @@ -2093,10 +2090,10 @@ yyreduce: case 15: /* Line 1806 of yacc.c */ -#line 293 "parser.y" +#line 306 "parser.y" { BEGIN_ACTION; - _gmx_sel_handle_help_cmd(process_value_list((yyvsp[(2) - (2)].val)), scanner); + _gmx_sel_handle_help_cmd(get((yyvsp[(2) - (2)].vlist)), scanner); END_ACTION; } break; @@ -2104,18 +2101,23 @@ yyreduce: case 16: /* Line 1806 of yacc.c */ -#line 300 "parser.y" - { (yyval.val) = NULL; } +#line 314 "parser.y" + { + BEGIN_ACTION; + set((yyval.vlist), SelectionParserValue::createList()); + END_ACTION; + } break; case 17: /* Line 1806 of yacc.c */ -#line 302 "parser.y" +#line 320 "parser.y" { BEGIN_ACTION; - (yyval.val) = _gmx_selexpr_create_value(STR_VALUE); - (yyval.val)->u.s = (yyvsp[(2) - (2)].str); (yyval.val)->next = (yyvsp[(1) - (2)].val); + SelectionParserValueListPointer list(get((yyvsp[(1) - (2)].vlist))); + list->push_back(SelectionParserValue::createString((yyvsp[(2) - (2)].str))); + set((yyval.vlist), move(list)); END_ACTION; } break; @@ -2123,14 +2125,14 @@ yyreduce: case 18: /* Line 1806 of yacc.c */ -#line 311 "parser.y" +#line 330 "parser.y" { (yyval.sel) = (yyvsp[(1) - (1)].sel); } break; case 19: /* Line 1806 of yacc.c */ -#line 313 "parser.y" +#line 332 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_init_position(get((yyvsp[(1) - (1)].sel)), NULL, scanner)); @@ -2142,14 +2144,14 @@ yyreduce: case 20: /* Line 1806 of yacc.c */ -#line 319 "parser.y" +#line 338 "parser.y" { (yyval.sel) = (yyvsp[(2) - (3)].sel); } break; case 21: /* Line 1806 of yacc.c */ -#line 321 "parser.y" +#line 340 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_init_modifier((yyvsp[(2) - (3)].meth), get((yyvsp[(3) - (3)].plist)), get((yyvsp[(1) - (3)].sel)), scanner)); @@ -2161,63 +2163,63 @@ yyreduce: case 22: /* Line 1806 of yacc.c */ -#line 334 "parser.y" +#line 353 "parser.y" { (yyval.i) = (yyvsp[(1) - (1)].i); } break; case 23: /* Line 1806 of yacc.c */ -#line 335 "parser.y" +#line 354 "parser.y" { (yyval.i) = -(yyvsp[(2) - (2)].i); } break; case 24: /* Line 1806 of yacc.c */ -#line 339 "parser.y" +#line 358 "parser.y" { (yyval.r) = (yyvsp[(1) - (1)].r); } break; case 25: /* Line 1806 of yacc.c */ -#line 340 "parser.y" +#line 359 "parser.y" { (yyval.r) = -(yyvsp[(2) - (2)].r); } break; case 26: /* Line 1806 of yacc.c */ -#line 343 "parser.y" +#line 362 "parser.y" { (yyval.r) = (yyvsp[(1) - (1)].i); } break; case 27: /* Line 1806 of yacc.c */ -#line 344 "parser.y" +#line 363 "parser.y" { (yyval.r) = (yyvsp[(1) - (1)].r); } break; case 28: /* Line 1806 of yacc.c */ -#line 347 "parser.y" +#line 366 "parser.y" { (yyval.str) = (yyvsp[(1) - (1)].str); } break; case 29: /* Line 1806 of yacc.c */ -#line 348 "parser.y" +#line 367 "parser.y" { (yyval.str) = (yyvsp[(1) - (1)].str); } break; case 30: /* Line 1806 of yacc.c */ -#line 357 "parser.y" +#line 376 "parser.y" { BEGIN_ACTION; SelectionTreeElementPointer arg(get((yyvsp[(2) - (2)].sel))); @@ -2233,7 +2235,7 @@ yyreduce: case 31: /* Line 1806 of yacc.c */ -#line 368 "parser.y" +#line 387 "parser.y" { BEGIN_ACTION; SelectionTreeElementPointer arg1(get((yyvsp[(1) - (3)].sel))), arg2(get((yyvsp[(3) - (3)].sel))); @@ -2249,7 +2251,7 @@ yyreduce: case 32: /* Line 1806 of yacc.c */ -#line 379 "parser.y" +#line 398 "parser.y" { BEGIN_ACTION; SelectionTreeElementPointer arg1(get((yyvsp[(1) - (3)].sel))), arg2(get((yyvsp[(3) - (3)].sel))); @@ -2265,16 +2267,17 @@ yyreduce: case 33: /* Line 1806 of yacc.c */ -#line 389 "parser.y" +#line 408 "parser.y" { (yyval.sel) = (yyvsp[(2) - (3)].sel); } break; case 34: /* Line 1806 of yacc.c */ -#line 394 "parser.y" +#line 413 "parser.y" { BEGIN_ACTION; + scoped_ptr_sfree opGuard((yyvsp[(2) - (3)].str)); set((yyval.sel), _gmx_sel_init_comparison(get((yyvsp[(1) - (3)].sel)), get((yyvsp[(3) - (3)].sel)), (yyvsp[(2) - (3)].str), scanner)); CHECK_SEL((yyval.sel)); END_ACTION; @@ -2284,7 +2287,7 @@ yyreduce: case 35: /* Line 1806 of yacc.c */ -#line 404 "parser.y" +#line 424 "parser.y" { BEGIN_ACTION; scoped_ptr_sfree nameGuard((yyvsp[(2) - (2)].str)); @@ -2297,7 +2300,7 @@ yyreduce: case 36: /* Line 1806 of yacc.c */ -#line 412 "parser.y" +#line 432 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_init_group_by_id((yyvsp[(2) - (2)].i), scanner)); @@ -2309,25 +2312,25 @@ yyreduce: case 37: /* Line 1806 of yacc.c */ -#line 421 "parser.y" +#line 441 "parser.y" { (yyval.str) = NULL; } break; case 38: /* Line 1806 of yacc.c */ -#line 422 "parser.y" +#line 442 "parser.y" { (yyval.str) = (yyvsp[(1) - (1)].str); } break; case 39: /* Line 1806 of yacc.c */ -#line 427 "parser.y" +#line 447 "parser.y" { BEGIN_ACTION; scoped_ptr_sfree posmodGuard((yyvsp[(1) - (2)].str)); - set((yyval.sel), _gmx_sel_init_keyword((yyvsp[(2) - (2)].meth), NULL, (yyvsp[(1) - (2)].str), scanner)); + set((yyval.sel), _gmx_sel_init_keyword((yyvsp[(2) - (2)].meth), SelectionParserValueListPointer(), (yyvsp[(1) - (2)].str), scanner)); CHECK_SEL((yyval.sel)); END_ACTION; } @@ -2336,11 +2339,11 @@ yyreduce: case 40: /* Line 1806 of yacc.c */ -#line 435 "parser.y" +#line 455 "parser.y" { BEGIN_ACTION; scoped_ptr_sfree posmodGuard((yyvsp[(1) - (3)].str)); - set((yyval.sel), _gmx_sel_init_keyword((yyvsp[(2) - (3)].meth), process_value_list((yyvsp[(3) - (3)].val)), (yyvsp[(1) - (3)].str), scanner)); + set((yyval.sel), _gmx_sel_init_keyword((yyvsp[(2) - (3)].meth), get((yyvsp[(3) - (3)].vlist)), (yyvsp[(1) - (3)].str), scanner)); CHECK_SEL((yyval.sel)); END_ACTION; } @@ -2349,11 +2352,11 @@ yyreduce: case 41: /* Line 1806 of yacc.c */ -#line 443 "parser.y" +#line 463 "parser.y" { BEGIN_ACTION; scoped_ptr_sfree posmodGuard((yyvsp[(1) - (3)].str)); - set((yyval.sel), _gmx_sel_init_keyword((yyvsp[(2) - (3)].meth), process_value_list((yyvsp[(3) - (3)].val)), (yyvsp[(1) - (3)].str), scanner)); + set((yyval.sel), _gmx_sel_init_keyword((yyvsp[(2) - (3)].meth), get((yyvsp[(3) - (3)].vlist)), (yyvsp[(1) - (3)].str), scanner)); CHECK_SEL((yyval.sel)); END_ACTION; } @@ -2362,7 +2365,7 @@ yyreduce: case 42: /* Line 1806 of yacc.c */ -#line 454 "parser.y" +#line 474 "parser.y" { BEGIN_ACTION; scoped_ptr_sfree posmodGuard((yyvsp[(1) - (3)].str)); @@ -2375,7 +2378,7 @@ yyreduce: case 43: /* Line 1806 of yacc.c */ -#line 469 "parser.y" +#line 489 "parser.y" { BEGIN_ACTION; SelectionTreeElementPointer sel( @@ -2391,7 +2394,7 @@ yyreduce: case 44: /* Line 1806 of yacc.c */ -#line 480 "parser.y" +#line 500 "parser.y" { BEGIN_ACTION; SelectionTreeElementPointer sel( @@ -2407,11 +2410,11 @@ yyreduce: case 45: /* Line 1806 of yacc.c */ -#line 494 "parser.y" +#line 514 "parser.y" { BEGIN_ACTION; scoped_ptr_sfree posmodGuard((yyvsp[(1) - (2)].str)); - set((yyval.sel), _gmx_sel_init_keyword((yyvsp[(2) - (2)].meth), NULL, (yyvsp[(1) - (2)].str), scanner)); + set((yyval.sel), _gmx_sel_init_keyword((yyvsp[(2) - (2)].meth), SelectionParserValueListPointer(), (yyvsp[(1) - (2)].str), scanner)); CHECK_SEL((yyval.sel)); END_ACTION; } @@ -2420,7 +2423,7 @@ yyreduce: case 46: /* Line 1806 of yacc.c */ -#line 502 "parser.y" +#line 522 "parser.y" { BEGIN_ACTION; scoped_ptr_sfree posmodGuard((yyvsp[(1) - (3)].str)); @@ -2433,7 +2436,7 @@ yyreduce: case 47: /* Line 1806 of yacc.c */ -#line 513 "parser.y" +#line 533 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_init_arithmetic(get((yyvsp[(1) - (3)].sel)), get((yyvsp[(3) - (3)].sel)), '+', scanner)); @@ -2444,7 +2447,7 @@ yyreduce: case 48: /* Line 1806 of yacc.c */ -#line 519 "parser.y" +#line 539 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_init_arithmetic(get((yyvsp[(1) - (3)].sel)), get((yyvsp[(3) - (3)].sel)), '-', scanner)); @@ -2455,7 +2458,7 @@ yyreduce: case 49: /* Line 1806 of yacc.c */ -#line 525 "parser.y" +#line 545 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_init_arithmetic(get((yyvsp[(1) - (3)].sel)), get((yyvsp[(3) - (3)].sel)), '*', scanner)); @@ -2466,7 +2469,7 @@ yyreduce: case 50: /* Line 1806 of yacc.c */ -#line 531 "parser.y" +#line 551 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_init_arithmetic(get((yyvsp[(1) - (3)].sel)), get((yyvsp[(3) - (3)].sel)), '/', scanner)); @@ -2477,7 +2480,7 @@ yyreduce: case 51: /* Line 1806 of yacc.c */ -#line 537 "parser.y" +#line 557 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_init_arithmetic(get((yyvsp[(2) - (2)].sel)), SelectionTreeElementPointer(), '-', scanner)); @@ -2488,7 +2491,7 @@ yyreduce: case 52: /* Line 1806 of yacc.c */ -#line 543 "parser.y" +#line 563 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_init_arithmetic(get((yyvsp[(1) - (3)].sel)), get((yyvsp[(3) - (3)].sel)), '^', scanner)); @@ -2499,14 +2502,14 @@ yyreduce: case 53: /* Line 1806 of yacc.c */ -#line 548 "parser.y" +#line 568 "parser.y" { (yyval.sel) = (yyvsp[(2) - (3)].sel); } break; case 54: /* Line 1806 of yacc.c */ -#line 556 "parser.y" +#line 576 "parser.y" { BEGIN_ACTION; SelectionTreeElementPointer sel( @@ -2522,11 +2525,11 @@ yyreduce: case 55: /* Line 1806 of yacc.c */ -#line 567 "parser.y" +#line 587 "parser.y" { BEGIN_ACTION; scoped_ptr_sfree posmodGuard((yyvsp[(1) - (2)].str)); - set((yyval.sel), _gmx_sel_init_keyword((yyvsp[(2) - (2)].meth), NULL, (yyvsp[(1) - (2)].str), scanner)); + set((yyval.sel), _gmx_sel_init_keyword((yyvsp[(2) - (2)].meth), SelectionParserValueListPointer(), (yyvsp[(1) - (2)].str), scanner)); CHECK_SEL((yyval.sel)); END_ACTION; } @@ -2535,7 +2538,7 @@ yyreduce: case 56: /* Line 1806 of yacc.c */ -#line 582 "parser.y" +#line 602 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_init_const_position((yyvsp[(2) - (7)].r), (yyvsp[(4) - (7)].r), (yyvsp[(6) - (7)].r))); @@ -2546,14 +2549,14 @@ yyreduce: case 57: /* Line 1806 of yacc.c */ -#line 590 "parser.y" +#line 610 "parser.y" { (yyval.sel) = (yyvsp[(2) - (3)].sel); } break; case 58: /* Line 1806 of yacc.c */ -#line 595 "parser.y" +#line 615 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_init_method((yyvsp[(1) - (2)].meth), get((yyvsp[(2) - (2)].plist)), NULL, scanner)); @@ -2565,7 +2568,7 @@ yyreduce: case 59: /* Line 1806 of yacc.c */ -#line 605 "parser.y" +#line 625 "parser.y" { BEGIN_ACTION; scoped_ptr_sfree keywordGuard((yyvsp[(1) - (3)].str)); @@ -2578,7 +2581,7 @@ yyreduce: case 60: /* Line 1806 of yacc.c */ -#line 619 "parser.y" +#line 639 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_init_variable_ref(get((yyvsp[(1) - (1)].sel)))); @@ -2589,7 +2592,7 @@ yyreduce: case 61: /* Line 1806 of yacc.c */ -#line 627 "parser.y" +#line 647 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_init_variable_ref(get((yyvsp[(1) - (1)].sel)))); @@ -2600,7 +2603,7 @@ yyreduce: case 62: /* Line 1806 of yacc.c */ -#line 635 "parser.y" +#line 655 "parser.y" { BEGIN_ACTION; set((yyval.sel), _gmx_sel_init_variable_ref(get((yyvsp[(1) - (1)].sel)))); @@ -2611,21 +2614,21 @@ yyreduce: case 63: /* Line 1806 of yacc.c */ -#line 648 "parser.y" +#line 668 "parser.y" { (yyval.plist) = (yyvsp[(1) - (1)].plist); } break; case 64: /* Line 1806 of yacc.c */ -#line 650 "parser.y" +#line 670 "parser.y" { (yyval.plist) = (yyvsp[(1) - (2)].plist); } break; case 65: /* Line 1806 of yacc.c */ -#line 655 "parser.y" +#line 675 "parser.y" { BEGIN_ACTION; set((yyval.plist), SelectionParserParameter::createList()); @@ -2636,7 +2639,7 @@ yyreduce: case 66: /* Line 1806 of yacc.c */ -#line 661 "parser.y" +#line 681 "parser.y" { BEGIN_ACTION; SelectionParserParameterListPointer list(get((yyvsp[(1) - (2)].plist))); @@ -2649,11 +2652,11 @@ yyreduce: case 67: /* Line 1806 of yacc.c */ -#line 672 "parser.y" +#line 692 "parser.y" { BEGIN_ACTION; scoped_ptr_sfree nameGuard((yyvsp[(1) - (2)].str)); - set((yyval.param), SelectionParserParameter::create((yyvsp[(1) - (2)].str), process_value_list((yyvsp[(2) - (2)].val)))); + set((yyval.param), SelectionParserParameter::create((yyvsp[(1) - (2)].str), get((yyvsp[(2) - (2)].vlist)))); END_ACTION; } break; @@ -2661,206 +2664,226 @@ yyreduce: case 68: /* Line 1806 of yacc.c */ -#line 680 "parser.y" - { (yyval.val) = NULL; } +#line 700 "parser.y" + { (yyval.vlist) = (yyvsp[(1) - (1)].vlist); } break; case 69: /* Line 1806 of yacc.c */ -#line 681 "parser.y" - { (yyval.val) = (yyvsp[(1) - (1)].val); } +#line 701 "parser.y" + { (yyval.vlist) = (yyvsp[(2) - (3)].vlist); } break; case 70: /* Line 1806 of yacc.c */ -#line 682 "parser.y" - { (yyval.val) = (yyvsp[(2) - (3)].val); } +#line 706 "parser.y" + { + BEGIN_ACTION; + set((yyval.vlist), SelectionParserValue::createList()); + END_ACTION; + } break; case 71: /* Line 1806 of yacc.c */ -#line 686 "parser.y" - { (yyval.val) = (yyvsp[(1) - (1)].val); } +#line 712 "parser.y" + { + BEGIN_ACTION; + SelectionParserValueListPointer list(get((yyvsp[(1) - (2)].vlist))); + list->push_back(get((yyvsp[(2) - (2)].val))); + set((yyval.vlist), move(list)); + END_ACTION; + } break; case 72: /* Line 1806 of yacc.c */ -#line 688 "parser.y" - { (yyvsp[(2) - (2)].val)->next = (yyvsp[(1) - (2)].val); (yyval.val) = (yyvsp[(2) - (2)].val); } +#line 720 "parser.y" + { + BEGIN_ACTION; + SelectionParserValueListPointer list(get((yyvsp[(1) - (3)].vlist))); + list->push_back(get((yyvsp[(3) - (3)].val))); + set((yyval.vlist), move(list)); + END_ACTION; + } break; case 73: /* Line 1806 of yacc.c */ -#line 690 "parser.y" - { (yyvsp[(3) - (3)].val)->next = (yyvsp[(1) - (3)].val); (yyval.val) = (yyvsp[(3) - (3)].val); } +#line 730 "parser.y" + { (yyval.vlist) = (yyvsp[(1) - (1)].vlist); } break; case 74: /* Line 1806 of yacc.c */ -#line 694 "parser.y" - { (yyval.val) = (yyvsp[(1) - (1)].val); } +#line 731 "parser.y" + { (yyval.vlist) = (yyvsp[(2) - (3)].vlist); } break; case 75: /* Line 1806 of yacc.c */ -#line 695 "parser.y" - { (yyval.val) = (yyvsp[(2) - (3)].val); } +#line 736 "parser.y" + { + BEGIN_ACTION; + set((yyval.vlist), SelectionParserValue::createList(get((yyvsp[(1) - (1)].val)))); + END_ACTION; + } break; case 76: /* Line 1806 of yacc.c */ -#line 699 "parser.y" - { (yyval.val) = (yyvsp[(1) - (1)].val); } +#line 742 "parser.y" + { + BEGIN_ACTION; + SelectionParserValueListPointer list(get((yyvsp[(1) - (2)].vlist))); + list->push_back(get((yyvsp[(2) - (2)].val))); + set((yyval.vlist), move(list)); + END_ACTION; + } break; case 77: /* Line 1806 of yacc.c */ -#line 701 "parser.y" - { (yyvsp[(2) - (2)].val)->next = (yyvsp[(1) - (2)].val); (yyval.val) = (yyvsp[(2) - (2)].val); } +#line 750 "parser.y" + { + BEGIN_ACTION; + SelectionParserValueListPointer list(get((yyvsp[(1) - (3)].vlist))); + list->push_back(get((yyvsp[(3) - (3)].val))); + set((yyval.vlist), move(list)); + END_ACTION; + } break; case 78: /* Line 1806 of yacc.c */ -#line 703 "parser.y" - { (yyvsp[(3) - (3)].val)->next = (yyvsp[(1) - (3)].val); (yyval.val) = (yyvsp[(3) - (3)].val); } - break; - - case 79: - -/* Line 1806 of yacc.c */ -#line 707 "parser.y" +#line 760 "parser.y" { BEGIN_ACTION; - (yyval.val) = _gmx_selexpr_create_value_expr(get((yyvsp[(1) - (1)].sel))); + set((yyval.val), SelectionParserValue::createExpr(get((yyvsp[(1) - (1)].sel)))); END_ACTION; } break; - case 80: + case 79: /* Line 1806 of yacc.c */ -#line 713 "parser.y" +#line 766 "parser.y" { BEGIN_ACTION; - (yyval.val) = _gmx_selexpr_create_value_expr(get((yyvsp[(1) - (1)].sel))); + set((yyval.val), SelectionParserValue::createExpr(get((yyvsp[(1) - (1)].sel)))); END_ACTION; } break; - case 81: + case 80: /* Line 1806 of yacc.c */ -#line 719 "parser.y" +#line 772 "parser.y" { BEGIN_ACTION; - (yyval.val) = _gmx_selexpr_create_value_expr(get((yyvsp[(1) - (1)].sel))); + set((yyval.val), SelectionParserValue::createExpr(get((yyvsp[(1) - (1)].sel)))); END_ACTION; } break; - case 82: + case 81: /* Line 1806 of yacc.c */ -#line 725 "parser.y" +#line 778 "parser.y" { BEGIN_ACTION; - (yyval.val) = _gmx_selexpr_create_value_expr(get((yyvsp[(1) - (1)].sel))); + set((yyval.val), SelectionParserValue::createExpr(get((yyvsp[(1) - (1)].sel)))); END_ACTION; } break; - case 83: + case 82: /* Line 1806 of yacc.c */ -#line 730 "parser.y" +#line 783 "parser.y" { (yyval.val) = (yyvsp[(1) - (1)].val); } break; - case 84: + case 83: /* Line 1806 of yacc.c */ -#line 735 "parser.y" +#line 788 "parser.y" { BEGIN_ACTION; - (yyval.val) = _gmx_selexpr_create_value(INT_VALUE); - (yyval.val)->u.i.i1 = (yyval.val)->u.i.i2 = (yyvsp[(1) - (1)].i); + set((yyval.val), SelectionParserValue::createInteger((yyvsp[(1) - (1)].i))); END_ACTION; } break; - case 85: + case 84: /* Line 1806 of yacc.c */ -#line 742 "parser.y" +#line 794 "parser.y" { BEGIN_ACTION; - (yyval.val) = _gmx_selexpr_create_value(REAL_VALUE); - (yyval.val)->u.r.r1 = (yyval.val)->u.r.r2 = (yyvsp[(1) - (1)].r); + set((yyval.val), SelectionParserValue::createReal((yyvsp[(1) - (1)].r))); END_ACTION; } break; - case 86: + case 85: /* Line 1806 of yacc.c */ -#line 749 "parser.y" +#line 800 "parser.y" { BEGIN_ACTION; - (yyval.val) = _gmx_selexpr_create_value(STR_VALUE); - (yyval.val)->u.s = (yyvsp[(1) - (1)].str); + scoped_ptr_sfree stringGuard((yyvsp[(1) - (1)].str)); + set((yyval.val), SelectionParserValue::createString((yyvsp[(1) - (1)].str))); END_ACTION; } break; - case 87: + case 86: /* Line 1806 of yacc.c */ -#line 755 "parser.y" +#line 806 "parser.y" { (yyval.val) = (yyvsp[(1) - (1)].val); } break; - case 88: + case 87: /* Line 1806 of yacc.c */ -#line 760 "parser.y" +#line 811 "parser.y" { BEGIN_ACTION; - (yyval.val) = _gmx_selexpr_create_value(INT_VALUE); - (yyval.val)->u.i.i1 = (yyvsp[(1) - (3)].i); (yyval.val)->u.i.i2 = (yyvsp[(3) - (3)].i); + set((yyval.val), SelectionParserValue::createIntegerRange((yyvsp[(1) - (3)].i), (yyvsp[(3) - (3)].i))); END_ACTION; } break; - case 89: + case 88: /* Line 1806 of yacc.c */ -#line 767 "parser.y" +#line 817 "parser.y" { BEGIN_ACTION; - (yyval.val) = _gmx_selexpr_create_value(REAL_VALUE); - (yyval.val)->u.r.r1 = (yyvsp[(1) - (3)].i); (yyval.val)->u.r.r2 = (yyvsp[(3) - (3)].r); + set((yyval.val), SelectionParserValue::createRealRange((yyvsp[(1) - (3)].i), (yyvsp[(3) - (3)].r))); END_ACTION; } break; - case 90: + case 89: /* Line 1806 of yacc.c */ -#line 774 "parser.y" +#line 823 "parser.y" { BEGIN_ACTION; - (yyval.val) = _gmx_selexpr_create_value(REAL_VALUE); - (yyval.val)->u.r.r1 = (yyvsp[(1) - (3)].r); (yyval.val)->u.r.r2 = (yyvsp[(3) - (3)].r); + set((yyval.val), SelectionParserValue::createRealRange((yyvsp[(1) - (3)].r), (yyvsp[(3) - (3)].r))); END_ACTION; } break; @@ -2868,7 +2891,7 @@ yyreduce: /* Line 1806 of yacc.c */ -#line 2872 "parser.cpp" +#line 2895 "parser.cpp" default: break; } /* User semantic actions sometimes alter yychar, and that requires diff --git a/src/gromacs/selection/parser.h b/src/gromacs/selection/parser.h index 58c87b540a..1d1eb0e7de 100644 --- a/src/gromacs/selection/parser.h +++ b/src/gromacs/selection/parser.h @@ -33,7 +33,7 @@ /* "%code requires" blocks. */ /* Line 2068 of yacc.c */ -#line 65 "parser.y" +#line 68 "parser.y" #include "parsetree.h" #include "selelem.h" @@ -92,16 +92,16 @@ typedef union YYSTYPE { /* Line 2068 of yacc.c */ -#line 70 "parser.y" +#line 73 "parser.y" int i; real r; char *str; struct gmx_ana_selmethod_t *meth; - gmx::SelectionTreeElementPointer *sel; - - struct t_selexpr_value *val; + gmx::SelectionTreeElementPointer *sel; + gmx::SelectionParserValue *val; + gmx::SelectionParserValueListPointer *vlist; gmx::SelectionParserParameterPointer *param; gmx::SelectionParserParameterListPointer *plist; diff --git a/src/gromacs/selection/parser.y b/src/gromacs/selection/parser.y index 7137badef4..3f7b8a43c7 100644 --- a/src/gromacs/selection/parser.y +++ b/src/gromacs/selection/parser.y @@ -50,6 +50,9 @@ #include "parser_internal.h" using gmx::scoped_ptr_sfree; +using gmx::SelectionParserValue; +using gmx::SelectionParserValueList; +using gmx::SelectionParserValueListPointer; using gmx::SelectionParserParameter; using gmx::SelectionParserParameterList; using gmx::SelectionParserParameterPointer; @@ -73,9 +76,9 @@ using gmx::SelectionTreeElementPointer; char *str; struct gmx_ana_selmethod_t *meth; - gmx::SelectionTreeElementPointer *sel; - - struct t_selexpr_value *val; + gmx::SelectionTreeElementPointer *sel; + gmx::SelectionParserValue *val; + gmx::SelectionParserValueListPointer *vlist; gmx::SelectionParserParameterPointer *param; gmx::SelectionParserParameterListPointer *plist; }; @@ -160,20 +163,20 @@ using gmx::SelectionTreeElementPointer; /* Parameter/value non-terminals */ %type method_params method_param_list %type method_param -%type value_list value_list_contents value_item value_item_range -%type basic_value_list basic_value_list_contents basic_value_item -%type help_topic - -%destructor { free($$); } HELP_TOPIC STR IDENTIFIER KEYWORD_POS CMP_OP string -%destructor { if($$) free($$); } PARAM pos_mod -%destructor { delete $$; } commands command cmd_plain selection -%destructor { delete $$; } sel_expr num_expr str_expr pos_expr -%destructor { delete $$; } method_params method_param_list method_param -%destructor { _gmx_selexpr_free_values($$); } value_list value_list_contents value_item value_item_range -%destructor { _gmx_selexpr_free_values($$); } basic_value_list basic_value_list_contents basic_value_item -%destructor { _gmx_selexpr_free_values($$); } help_topic - -%expect 50 +%type value_list value_list_contents basic_value_list basic_value_list_contents +%type value_item value_item_range basic_value_item +%type help_topic + +%destructor { free($$); } HELP_TOPIC STR IDENTIFIER KEYWORD_POS CMP_OP string +%destructor { if($$) free($$); } PARAM pos_mod +%destructor { delete $$; } commands command cmd_plain selection +%destructor { delete $$; } sel_expr num_expr str_expr pos_expr +%destructor { delete $$; } method_params method_param_list method_param +%destructor { delete $$; } value_list value_list_contents basic_value_list basic_value_list_contents +%destructor { delete $$; } value_item value_item_range basic_value_item +%destructor { delete $$; } help_topic + +%expect 35 %debug %pure-parser %define api.push-pull push @@ -184,7 +187,12 @@ using gmx::SelectionTreeElementPointer; %% /* The start rule: allow one or more commands */ -commands: /* empty */ { $$ = NULL; } +commands: /* empty */ + { + BEGIN_ACTION; + set_empty($$); + END_ACTION; + } | commands command { BEGIN_ACTION; @@ -200,7 +208,6 @@ command: cmd_plain CMD_SEP { $$ = $1; } | error CMD_SEP { BEGIN_ACTION; - $$ = NULL; _gmx_selparser_error(scanner, "invalid selection '%s'", _gmx_sel_lexer_pselstr(scanner)); _gmx_sel_lexer_clear_method_stack(scanner); @@ -213,6 +220,7 @@ command: cmd_plain CMD_SEP { $$ = $1; } { YYABORT; } + set_empty($$); END_ACTION; } ; @@ -221,11 +229,16 @@ command: cmd_plain CMD_SEP { $$ = $1; } cmd_plain: /* empty */ { BEGIN_ACTION; - $$ = NULL; _gmx_sel_handle_empty_cmd(scanner); + set_empty($$); + END_ACTION; + } + | help_request + { + BEGIN_ACTION; + set_empty($$); END_ACTION; } - | help_request { $$ = NULL; } | TOK_INT { BEGIN_ACTION; @@ -292,17 +305,23 @@ help_request: HELP help_topic { BEGIN_ACTION; - _gmx_sel_handle_help_cmd(process_value_list($2), scanner); + _gmx_sel_handle_help_cmd(get($2), scanner); END_ACTION; } ; -help_topic: /* empty */ { $$ = NULL; } +help_topic: /* empty */ + { + BEGIN_ACTION; + set($$, SelectionParserValue::createList()); + END_ACTION; + } | help_topic HELP_TOPIC { BEGIN_ACTION; - $$ = _gmx_selexpr_create_value(STR_VALUE); - $$->u.s = $2; $$->next = $1; + SelectionParserValueListPointer list(get($1)); + list->push_back(SelectionParserValue::createString($2)); + set($$, move(list)); END_ACTION; } ; @@ -393,6 +412,7 @@ sel_expr: NOT sel_expr sel_expr: num_expr CMP_OP num_expr { BEGIN_ACTION; + scoped_ptr_sfree opGuard($2); set($$, _gmx_sel_init_comparison(get($1), get($3), $2, scanner)); CHECK_SEL($$); END_ACTION; @@ -427,7 +447,7 @@ sel_expr: pos_mod KEYWORD_GROUP { BEGIN_ACTION; scoped_ptr_sfree posmodGuard($1); - set($$, _gmx_sel_init_keyword($2, NULL, $1, scanner)); + set($$, _gmx_sel_init_keyword($2, SelectionParserValueListPointer(), $1, scanner)); CHECK_SEL($$); END_ACTION; } @@ -435,7 +455,7 @@ sel_expr: pos_mod KEYWORD_GROUP { BEGIN_ACTION; scoped_ptr_sfree posmodGuard($1); - set($$, _gmx_sel_init_keyword($2, process_value_list($3), $1, scanner)); + set($$, _gmx_sel_init_keyword($2, get($3), $1, scanner)); CHECK_SEL($$); END_ACTION; } @@ -443,7 +463,7 @@ sel_expr: pos_mod KEYWORD_GROUP { BEGIN_ACTION; scoped_ptr_sfree posmodGuard($1); - set($$, _gmx_sel_init_keyword($2, process_value_list($3), $1, scanner)); + set($$, _gmx_sel_init_keyword($2, get($3), $1, scanner)); CHECK_SEL($$); END_ACTION; } @@ -494,7 +514,7 @@ num_expr: pos_mod KEYWORD_NUMERIC %prec NUM_REDUCT { BEGIN_ACTION; scoped_ptr_sfree posmodGuard($1); - set($$, _gmx_sel_init_keyword($2, NULL, $1, scanner)); + set($$, _gmx_sel_init_keyword($2, SelectionParserValueListPointer(), $1, scanner)); CHECK_SEL($$); END_ACTION; } @@ -567,7 +587,7 @@ str_expr: string { BEGIN_ACTION; scoped_ptr_sfree posmodGuard($1); - set($$, _gmx_sel_init_keyword($2, NULL, $1, scanner)); + set($$, _gmx_sel_init_keyword($2, SelectionParserValueListPointer(), $1, scanner)); CHECK_SEL($$); END_ACTION; } @@ -672,22 +692,38 @@ method_param: { BEGIN_ACTION; scoped_ptr_sfree nameGuard($1); - set($$, SelectionParserParameter::create($1, process_value_list($2))); + set($$, SelectionParserParameter::create($1, get($2))); END_ACTION; } ; -value_list: /* empty */ { $$ = NULL; } - | value_list_contents { $$ = $1; } +value_list: value_list_contents { $$ = $1; } | '{' value_list_contents '}' { $$ = $2; } ; value_list_contents: - value_item { $$ = $1; } + /* empty */ + { + BEGIN_ACTION; + set($$, SelectionParserValue::createList()); + END_ACTION; + } | value_list_contents value_item - { $2->next = $1; $$ = $2; } + { + BEGIN_ACTION; + SelectionParserValueListPointer list(get($1)); + list->push_back(get($2)); + set($$, move(list)); + END_ACTION; + } | value_list_contents ',' value_item - { $3->next = $1; $$ = $3; } + { + BEGIN_ACTION; + SelectionParserValueListPointer list(get($1)); + list->push_back(get($3)); + set($$, move(list)); + END_ACTION; + } ; basic_value_list: @@ -696,35 +732,52 @@ basic_value_list: ; basic_value_list_contents: - basic_value_item { $$ = $1; } + basic_value_item + { + BEGIN_ACTION; + set($$, SelectionParserValue::createList(get($1))); + END_ACTION; + } | basic_value_list_contents basic_value_item - { $2->next = $1; $$ = $2; } + { + BEGIN_ACTION; + SelectionParserValueListPointer list(get($1)); + list->push_back(get($2)); + set($$, move(list)); + END_ACTION; + } | basic_value_list_contents ',' basic_value_item - { $3->next = $1; $$ = $3; } + { + BEGIN_ACTION; + SelectionParserValueListPointer list(get($1)); + list->push_back(get($3)); + set($$, move(list)); + END_ACTION; + } ; value_item: sel_expr %prec PARAM_REDUCT { BEGIN_ACTION; - $$ = _gmx_selexpr_create_value_expr(get($1)); + set($$, SelectionParserValue::createExpr(get($1))); END_ACTION; } | pos_expr %prec PARAM_REDUCT { BEGIN_ACTION; - $$ = _gmx_selexpr_create_value_expr(get($1)); + set($$, SelectionParserValue::createExpr(get($1))); END_ACTION; } | num_expr %prec PARAM_REDUCT { BEGIN_ACTION; - $$ = _gmx_selexpr_create_value_expr(get($1)); + set($$, SelectionParserValue::createExpr(get($1))); END_ACTION; } | str_expr %prec PARAM_REDUCT { BEGIN_ACTION; - $$ = _gmx_selexpr_create_value_expr(get($1)); + set($$, SelectionParserValue::createExpr(get($1))); END_ACTION; } | value_item_range { $$ = $1; } @@ -734,22 +787,20 @@ basic_value_item: integer_number %prec PARAM_REDUCT { BEGIN_ACTION; - $$ = _gmx_selexpr_create_value(INT_VALUE); - $$->u.i.i1 = $$->u.i.i2 = $1; + set($$, SelectionParserValue::createInteger($1)); END_ACTION; } | real_number %prec PARAM_REDUCT { BEGIN_ACTION; - $$ = _gmx_selexpr_create_value(REAL_VALUE); - $$->u.r.r1 = $$->u.r.r2 = $1; + set($$, SelectionParserValue::createReal($1)); END_ACTION; } | string %prec PARAM_REDUCT { BEGIN_ACTION; - $$ = _gmx_selexpr_create_value(STR_VALUE); - $$->u.s = $1; + scoped_ptr_sfree stringGuard($1); + set($$, SelectionParserValue::createString($1)); END_ACTION; } | value_item_range { $$ = $1; } @@ -759,22 +810,19 @@ value_item_range: integer_number TO integer_number { BEGIN_ACTION; - $$ = _gmx_selexpr_create_value(INT_VALUE); - $$->u.i.i1 = $1; $$->u.i.i2 = $3; + set($$, SelectionParserValue::createIntegerRange($1, $3)); END_ACTION; } | integer_number TO real_number { BEGIN_ACTION; - $$ = _gmx_selexpr_create_value(REAL_VALUE); - $$->u.r.r1 = $1; $$->u.r.r2 = $3; + set($$, SelectionParserValue::createRealRange($1, $3)); END_ACTION; } | real_number TO number { BEGIN_ACTION; - $$ = _gmx_selexpr_create_value(REAL_VALUE); - $$->u.r.r1 = $1; $$->u.r.r2 = $3; + set($$, SelectionParserValue::createRealRange($1, $3)); END_ACTION; } ; diff --git a/src/gromacs/selection/parser_internal.h b/src/gromacs/selection/parser_internal.h index 6cbae8e4aa..a16e7892fd 100644 --- a/src/gromacs/selection/parser_internal.h +++ b/src/gromacs/selection/parser_internal.h @@ -44,32 +44,15 @@ #include +#include + +#include "gromacs/utility/gmxassert.h" + #include "parsetree.h" #include "selelem.h" #include "scanner.h" -//! Helper method to reorder a list of parameter values. -static t_selexpr_value * -process_value_list(t_selexpr_value *values) -{ - t_selexpr_value *val, *pval, *nval; - - /* Count values (if needed) and reverse list */ - pval = NULL; - val = values; - while (val) - { - nval = val->next; - val->next = pval; - pval = val; - val = nval; - } - values = pval; - - return values; -} - //! Error handler needed by Bison. static void yyerror(yyscan_t scanner, char const *s) @@ -104,45 +87,72 @@ yyerror(yyscan_t scanner, char const *s) } //!\} +#ifndef GMX_CXX11 +//! No-op to enable use of same get()/set() implementation as with C++11. +static gmx::SelectionParserValue &move(gmx::SelectionParserValue &src) +{ + return src; +} +#endif + /*! \brief - * Retrieves a smart pointer from a semantic value. + * Retrieves a semantic value. * - * \param[in] src Semantic value to get the pointer from. - * \returns Retrieved smart pointer. + * \param[in] src Semantic value to get the value from. + * \returns Retrieved value. + * \throws unspecified Any exception thrown by the move constructor of + * ValueType (copy constructor if GMX_CXX11 is not set). * * There should be no statements that may throw exceptions in actions before - * this function has been called for all semantic values that have a smart - * pointer stored. Together with set(), this function abstracts away exception + * this function has been called for all semantic values that have a C++ object + * stored. Together with set(), this function abstracts away exception * safety issues that arise from the use of a plain pointer for storing the * semantic values. * - * Does not throw. + * Does not throw for smart pointer types. If used with types that may throw, + * the order of operations should be such that it is exception-safe. */ -template static -PointerType get(PointerType *src) +template static +ValueType get(ValueType *src) { - PointerType result; - if (src != NULL) - { - result.swap(*src); - delete src; - } - return move(result); + GMX_RELEASE_ASSERT(src != NULL, "Semantic value pointers should be non-NULL"); + boost::scoped_ptr srcGuard(src); + return ValueType(move(*src)); +} +/*! \brief + * Sets a semantic value. + * + * \tparam ValueType Type of value to set. + * \param[out] dest Semantic value to set (typically $$). + * \param[in] value Value to put into the semantic value. + * \throws std::bad_alloc if out of memory. + * \throws unspecified Any exception thrown by the move constructor of + * ValueType (copy constructor if GMX_CXX11 is not set). + * + * This should be the last statement before ::END_ACTION, except for a + * possible ::CHECK_SEL. + */ +template static +void set(ValueType *&dest, ValueType value) +{ + dest = new ValueType(move(value)); } /*! \brief - * Sets a smart pointer to a semantic value. + * Sets an empty semantic value. * + * \tparam ValueType Type of value to set (must be default constructible). * \param[out] dest Semantic value to set (typically $$). - * \param[in] value Pointer to put into the semantic value. * \throws std::bad_alloc if out of memory. + * \throws unspecified Any exception thrown by the default constructor of + * ValueType. * * This should be the last statement before ::END_ACTION, except for a * possible ::CHECK_SEL. */ -template static -void set(PointerType *&dest, PointerType value) +template static +void set_empty(ValueType *&dest) { - dest = new PointerType(move(value)); + dest = new ValueType; } /*! \brief * Checks that a valid tree was set. diff --git a/src/gromacs/selection/parsetree.cpp b/src/gromacs/selection/parsetree.cpp index fae07673ab..a2b8ebc7e3 100644 --- a/src/gromacs/selection/parsetree.cpp +++ b/src/gromacs/selection/parsetree.cpp @@ -248,6 +248,9 @@ #include "scanner.h" +using gmx::SelectionParserValue; +using gmx::SelectionParserValueList; +using gmx::SelectionParserValueListPointer; using gmx::SelectionParserParameter; using gmx::SelectionParserParameterList; using gmx::SelectionParserParameterListPointer; @@ -274,80 +277,46 @@ _gmx_selparser_handle_exception(yyscan_t scanner, const std::exception &/*ex*/) return false; } -/*! - * \param[in] type Type for the new value. - * \returns Pointer to the newly allocated value. - */ -t_selexpr_value * -_gmx_selexpr_create_value(e_selvalue_t type) +namespace gmx { - t_selexpr_value *value = new t_selexpr_value(); - value->type = type; - memset(&value->u, 0, sizeof(value->u)); - value->next = NULL; - return value; -} -/*! - * \param[in] expr Expression for the value. - * \returns Pointer to the newly allocated value. +/******************************************************************** + * SelectionParserValue */ -t_selexpr_value * -_gmx_selexpr_create_value_expr(const SelectionTreeElementPointer &expr) + +SelectionParserValue::SelectionParserValue(e_selvalue_t type) + : type(type) { - t_selexpr_value *value = new t_selexpr_value(); - value->type = expr->v.type; - value->expr = expr; - memset(&value->u, 0, sizeof(value->u)); - value->next = NULL; - return value; + memset(&u, 0, sizeof(u)); } -namespace gmx +SelectionParserValue::SelectionParserValue( + const SelectionTreeElementPointer &expr) + : type(expr->v.type), expr(expr) { + memset(&u, 0, sizeof(u)); +} + +/******************************************************************** + * SelectionParserParameter + */ -SelectionParserParameter::SelectionParserParameter(const char *name, - t_selexpr_value *value) - : name_(name != NULL ? name : ""), nval(0), value(value) +SelectionParserParameter::SelectionParserParameter( + const char *name, + SelectionParserValueListPointer values) + : name_(name != NULL ? name : ""), + values_(values ? move(values) + : SelectionParserValueListPointer(new SelectionParserValueList)) { - t_selexpr_value *val = value; - while (val != NULL) - { - ++nval; - val = val->next; - } } SelectionParserParameter::~SelectionParserParameter() { - _gmx_selexpr_free_values(value); } } // namespace gmx /*! - * \param value Pointer to the beginning of the value list to free. - * - * The expressions referenced by the values are also freed - * (to prevent this, set the expression to NULL before calling the function). - */ -void -_gmx_selexpr_free_values(t_selexpr_value *value) -{ - - while (value) - { - if (!value->expr && value->type == STR_VALUE) - { - sfree(value->u.s); - } - t_selexpr_value *old = value; - value = value->next; - delete old; - } -} - -/*! * \param[in,out] sel Root of the selection element tree to initialize. * \param[in] scanner Scanner data structure. * \returns 0 on success, an error code on error. @@ -643,7 +612,7 @@ _gmx_sel_init_arithmetic(const SelectionTreeElementPointer &left, SelectionTreeElementPointer _gmx_sel_init_comparison(const SelectionTreeElementPointer &left, const SelectionTreeElementPointer &right, - char *cmpop, yyscan_t scanner) + const char *cmpop, yyscan_t scanner) { gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner); gmx::MessageStringContext context(errors, "In comparison initialization"); @@ -653,19 +622,16 @@ _gmx_sel_init_comparison(const SelectionTreeElementPointer &left, SelectionParserParameterList params; const char *name; - t_selexpr_value *value; - /* Create the parameter for the left expression */ + // Create the parameter for the left expression. name = left->v.type == INT_VALUE ? "int1" : "real1"; - value = _gmx_selexpr_create_value_expr(left); - params.push_back(SelectionParserParameter::create(name, value)); - /* Create the parameter for the right expression */ + params.push_back(SelectionParserParameter::createFromExpression(name, left)); + // Create the parameter for the right expression. name = right->v.type == INT_VALUE ? "int2" : "real2"; - value = _gmx_selexpr_create_value_expr(right); - params.push_back(SelectionParserParameter::create(name, value)); - /* Create the parameter for the operator */ - value = _gmx_selexpr_create_value(STR_VALUE); - value->u.s = cmpop; - params.push_back(SelectionParserParameter::create("op", value)); + params.push_back(SelectionParserParameter::createFromExpression(name, right)); + // Create the parameter for the operator. + params.push_back( + SelectionParserParameter::create( + "op", SelectionParserValue::createString(cmpop))); if (!_gmx_sel_parse_params(params, sel->u.expr.method->nparams, sel->u.expr.method->param, sel, scanner)) { @@ -686,7 +652,8 @@ _gmx_sel_init_comparison(const SelectionTreeElementPointer &left, * selection methods that do not take parameters. */ SelectionTreeElementPointer -_gmx_sel_init_keyword(gmx_ana_selmethod_t *method, t_selexpr_value *args, +_gmx_sel_init_keyword(gmx_ana_selmethod_t *method, + SelectionParserValueListPointer args, const char *rpost, yyscan_t scanner) { gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); @@ -717,7 +684,6 @@ _gmx_sel_init_keyword(gmx_ana_selmethod_t *method, t_selexpr_value *args, case REAL_VALUE: kwmethod = &sm_keyword_real; break; case STR_VALUE: kwmethod = &sm_keyword_str; break; default: - _gmx_selexpr_free_values(args); GMX_THROW(gmx::InternalError( "Unknown type for keyword selection")); } @@ -725,9 +691,9 @@ _gmx_sel_init_keyword(gmx_ana_selmethod_t *method, t_selexpr_value *args, root.reset(new SelectionTreeElement(SEL_EXPRESSION)); _gmx_selelem_set_method(root, kwmethod, scanner); SelectionParserParameterList params; - t_selexpr_value *value = _gmx_selexpr_create_value_expr(child); - params.push_back(SelectionParserParameter::create(NULL, value)); - params.push_back(SelectionParserParameter::create(NULL, args)); + params.push_back( + SelectionParserParameter::createFromExpression(NULL, child)); + params.push_back(SelectionParserParameter::create(NULL, move(args))); if (!_gmx_sel_parse_params(params, root->u.expr.method->nparams, root->u.expr.method->param, root, scanner)) { @@ -808,8 +774,8 @@ _gmx_sel_init_modifier(gmx_ana_selmethod_t *method, gmx::MessageStringContext context(errors, buf); _gmx_sel_finish_method(scanner); - SelectionTreeElementPointer mod(new SelectionTreeElement(SEL_MODIFIER)); - _gmx_selelem_set_method(mod, method, scanner); + SelectionTreeElementPointer modifier(new SelectionTreeElement(SEL_MODIFIER)); + _gmx_selelem_set_method(modifier, method, scanner); SelectionTreeElementPointer root; if (method->type == NO_VALUE) { @@ -818,18 +784,18 @@ _gmx_sel_init_modifier(gmx_ana_selmethod_t *method, { child = child->next; } - child->next = mod; + child->next = modifier; root = sel; } else { - t_selexpr_value *value = _gmx_selexpr_create_value_expr(sel); - params->push_front(SelectionParserParameter::create(NULL, value)); - root = mod; + params->push_front( + SelectionParserParameter::createFromExpression(NULL, sel)); + root = modifier; } /* Process the parameters */ - if (!_gmx_sel_parse_params(*params, mod->u.expr.method->nparams, - mod->u.expr.method->param, mod, scanner)) + if (!_gmx_sel_parse_params(*params, modifier->u.expr.method->nparams, + modifier->u.expr.method->param, modifier, scanner)) { return SelectionTreeElementPointer(); } @@ -860,8 +826,7 @@ _gmx_sel_init_position(const SelectionTreeElementPointer &expr, _gmx_selelem_set_kwpos_type(root.get(), type); /* Create the parameters for the parameter parser. */ SelectionParserParameterList params; - t_selexpr_value *value = _gmx_selexpr_create_value_expr(expr); - params.push_back(SelectionParserParameter::create(NULL, value)); + params.push_back(SelectionParserParameter::createFromExpression(NULL, expr)); /* Parse the parameters. */ if (!_gmx_sel_parse_params(params, root->u.expr.method->nparams, root->u.expr.method->param, root, scanner)) @@ -1250,10 +1215,9 @@ _gmx_sel_handle_empty_cmd(yyscan_t scanner) * \p topic is freed by this function. */ void -_gmx_sel_handle_help_cmd(t_selexpr_value *topic, yyscan_t scanner) +_gmx_sel_handle_help_cmd(const SelectionParserValueListPointer &topic, + yyscan_t scanner) { - boost::shared_ptr topicGuard(topic, &_gmx_selexpr_free_values); - gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); if (sc->rootHelp.get() == NULL) @@ -1265,11 +1229,10 @@ _gmx_sel_handle_help_cmd(t_selexpr_value *topic, yyscan_t scanner) gmx::HelpManager manager(*sc->rootHelp, context); try { - t_selexpr_value *value = topic; - while (value != NULL) + SelectionParserValueList::const_iterator value; + for (value = topic->begin(); value != topic->end(); ++value) { - manager.enterTopic(value->u.s); - value = value->next; + manager.enterTopic(value->stringValue()); } } catch (const gmx::InvalidInputError &ex) diff --git a/src/gromacs/selection/parsetree.h b/src/gromacs/selection/parsetree.h index ebc78b303d..428e23ec63 100644 --- a/src/gromacs/selection/parsetree.h +++ b/src/gromacs/selection/parsetree.h @@ -52,7 +52,9 @@ #include #include "gromacs/legacyheaders/types/simple.h" +#include "gromacs/legacyheaders/vec.h" +#include "gromacs/utility/gmxassert.h" #include "gromacs/utility/uniqueptr.h" #include "selelem.h" @@ -62,48 +64,187 @@ struct gmx_ana_indexgrps_t; struct gmx_ana_selmethod_t; struct gmx_ana_selparam_t; +namespace gmx +{ + +class SelectionParserValue; + +//! Container for a list of SelectionParserValue objects. +typedef std::list + SelectionParserValueList; +//! Smart pointer type for managing a SelectionParserValueList. +typedef gmx::gmx_unique_ptr::type + SelectionParserValueListPointer; + /*! \internal \brief * Describes a parsed value, possibly resulting from expression evaluation. * - * \todo - * Make this a proper class. + * All factory methods and the constructors may throw an std::bad_alloc if + * out of memory. + * + * \ingroup module_selection */ -typedef struct t_selexpr_value +class SelectionParserValue { - //! Returns true if the value comes from expression evaluation. - bool hasExpressionValue() const { return expr; } + public: + //! Allocates and initializes an empty value list. + static SelectionParserValueListPointer createList() + { + return SelectionParserValueListPointer(new SelectionParserValueList); + } + /*! \brief + * Allocates and initializes a value list with a single value. + * + * \param[in] value Initial value to put in the list. + * \returns Pointer to a new value list that contains \p value. + */ + static SelectionParserValueListPointer + createList(const SelectionParserValue &value) + { + SelectionParserValueListPointer list(new SelectionParserValueList); + list->push_back(value); + return move(list); + } + /*! \brief + * Allocates and initializes an expression value. + * + * \param[in] expr Root of the expression tree to assign to the value. + * \returns The newly created value. + */ + static SelectionParserValue + createExpr(const gmx::SelectionTreeElementPointer &expr) + { + return SelectionParserValue(expr); + } + /*! \brief + * Allocates and initializes a constant integer value. + * + * \param[in] value Integer value to assign to the value. + * \returns The newly created value. + */ + static SelectionParserValue createInteger(int value) + { + SelectionParserValue result(INT_VALUE); + result.u.i.i1 = result.u.i.i2 = value; + return result; + } + /*! \brief + * Allocates and initializes a constant integer range value. + * + * \param[in] from Beginning of the range to assign to the value. + * \param[in] to End of the range to assign to the value. + * \returns The newly created value. + */ + static SelectionParserValue createIntegerRange(int from, int to) + { + SelectionParserValue result(INT_VALUE); + result.u.i.i1 = from; + result.u.i.i2 = to; + return result; + } + /*! \brief + * Allocates and initializes a constant floating-point value. + * + * \param[in] value Floating-point value to assign to the value. + * \returns The newly created value. + */ + static SelectionParserValue createReal(real value) + { + SelectionParserValue result(REAL_VALUE); + result.u.r.r1 = result.u.r.r2 = value; + return result; + } + /*! \brief + * Allocates and initializes a constant floating-point range value. + * + * \param[in] from Beginning of the range to assign to the value. + * \param[in] to End of the range to assign to the value. + * \returns The newly created value. + */ + static SelectionParserValue createRealRange(real from, real to) + { + SelectionParserValue result(REAL_VALUE); + result.u.r.r1 = from; + result.u.r.r2 = to; + return result; + } + /*! \brief + * Allocates and initializes a constant string value. + * + * \param[in] value String to assign to the value. + * \returns The newly created value. + */ + static SelectionParserValue createString(const char *value) + { + SelectionParserValue result(STR_VALUE); + result.str = value; + return result; + } + /*! \brief + * Allocates and initializes a constant position value. + * + * \param[in] value Position vector to assign to the value. + * \returns The newly created value. + */ + static SelectionParserValue createPosition(rvec value) + { + SelectionParserValue result(POS_VALUE); + copy_rvec(value, result.u.x); + return result; + } - //! Type of the value. - e_selvalue_t type; - //! Expression pointer if the value is the result of an expression. - gmx::SelectionTreeElementPointer expr; - //! The actual value if \p expr is NULL. - union { - /** The integer value/range (\p type INT_VALUE); */ - struct { - /** Beginning of the range. */ - int i1; - /** End of the range; equals \p i1 for a single integer. */ - int i2; - } i; - /** The real value/range (\p type REAL_VALUE); */ - struct { - /** Beginning of the range. */ - real r1; - /** End of the range; equals \p r1 for a single number. */ - real r2; - } r; - /** The string value (\p type STR_VALUE); */ - char *s; - /** The position value (\p type POS_VALUE); */ - rvec x; - } u; - /** Pointer to the next value. */ - struct t_selexpr_value *next; -} t_selexpr_value; + //! Returns true if the value comes from expression evaluation. + bool hasExpressionValue() const { return expr; } -namespace gmx -{ + //! Returns the string value (\a type must be ::STR_VALUE). + const std::string &stringValue() const + { + GMX_ASSERT(type == STR_VALUE && !hasExpressionValue(), + "Attempted to retrieve string value from a non-string value"); + return str; + } + + // TODO: boost::any or similar could be nicer for the implementation. + //! Type of the value. + e_selvalue_t type; + //! Expression pointer if the value is the result of an expression. + gmx::SelectionTreeElementPointer expr; + //! String value for \a type ::STR_VALUE. + std::string str; + //! The actual value if \a expr is NULL and \a type is not ::STR_VALUE. + union { + //! The integer value/range (\a type ::INT_VALUE). + struct { + //! Beginning of the range. + int i1; + //! End of the range; equals \a i1 for a single integer. + int i2; + } i; + //! The real value/range (\a type ::REAL_VALUE). + struct { + //! Beginning of the range. + real r1; + //! End of the range; equals \a r1 for a single number. + real r2; + } r; + //! The position value (\a type ::POS_VALUE). + rvec x; + } u; + + private: + /*! \brief + * Initializes a new value. + * + * \param[in] type Type for the new value. + */ + explicit SelectionParserValue(e_selvalue_t type); + /*! \brief + * Initializes a new expression value. + * + * \param[in] expr Expression for the value. + */ + explicit SelectionParserValue(const gmx::SelectionTreeElementPointer &expr); +}; class SelectionParserParameter; @@ -134,44 +275,87 @@ class SelectionParserParameter /*! \brief * Allocates and initializes a parsed method parameter. * - * \param[in] name Name for the new parameter (can be NULL). - * \param[in] value List of values for the parameter. + * \param[in] name Name for the new parameter (can be NULL). + * \param[in] values List of values for the parameter. * \returns Pointer to the newly allocated parameter. * \throws std::bad_alloc if out of memory. */ static SelectionParserParameterPointer - create(const char *name, t_selexpr_value *value) + create(const char *name, SelectionParserValueListPointer values) { return SelectionParserParameterPointer( - new SelectionParserParameter(name, value)); + new SelectionParserParameter(name, move(values))); } - //! \copydoc create(const char *, t_selexpr_value *) + //! \copydoc create(const char *, SelectionParserValueListPointer) static SelectionParserParameterPointer - create(const std::string &name, t_selexpr_value *value) + create(const std::string &name, SelectionParserValueListPointer values) { return SelectionParserParameterPointer( - new SelectionParserParameter(name.c_str(), value)); + new SelectionParserParameter(name.c_str(), move(values))); + } + /*! \brief + * Allocates and initializes a parsed method parameter. + * + * \param[in] name Name for the new parameter (can be NULL). + * \param[in] value Value for the parameter. + * \returns Pointer to the newly allocated parameter. + * \throws std::bad_alloc if out of memory. + * + * This overload is a convenience wrapper for the case when creating + * parameters outside the actual Bison parser and only a single value + * is necessary. + */ + static SelectionParserParameterPointer + create(const char *name, const SelectionParserValue &value) + { + return create(name, SelectionParserValue::createList(value)); + } + /*! \brief + * Allocates and initializes a parsed method parameter. + * + * \param[in] name Name for the new parameter (can be NULL). + * \param[in] expr Expression value for the parameter. + * \returns Pointer to the newly allocated parameter. + * \throws std::bad_alloc if out of memory. + * + * This overload is a convenience wrapper for the case when creating + * parameters outside the actual Bison parser and only a single + * expression value is necessary. + */ + static SelectionParserParameterPointer + createFromExpression(const char *name, + const SelectionTreeElementPointer &expr) + { + return create(name, SelectionParserValue::createExpr(expr)); + } + //! \copydoc createFromExpression(const char *, const SelectionTreeElementPointer &) + static SelectionParserParameterPointer + createFromExpression(const std::string &name, + const SelectionTreeElementPointer &expr) + { + return create(name.c_str(), SelectionParserValue::createExpr(expr)); } /*! \brief * Initializes a parsed method parameter. * - * \param[in] name Name for the new parameter (can be NULL). - * \param[in] value List of values for the parameter. + * \param[in] name Name for the new parameter (can be NULL). + * \param[in] values List of values for the parameter. * \throws std::bad_alloc if out of memory. */ - SelectionParserParameter(const char *name, t_selexpr_value *value); + SelectionParserParameter(const char *name, + SelectionParserValueListPointer values); ~SelectionParserParameter(); //! Returns the name of the parameter (may be empty). const std::string &name() const { return name_; } + //! Returns the values for the parameter. + const SelectionParserValueList &values() const { return *values_; } //! Name of the parameter. std::string name_; - //! Number of values given for this parameter. - int nval; - //! Pointer to the first value. - struct t_selexpr_value *value; + //! Values for this parameter. + SelectionParserValueListPointer values_; }; } // namespace gmx @@ -183,16 +367,6 @@ _gmx_selparser_error(void *scanner, const char *fmt, ...); bool _gmx_selparser_handle_exception(void *scanner, const std::exception &ex); -/** Allocates and initializes a constant \c t_selexpr_value. */ -t_selexpr_value * -_gmx_selexpr_create_value(e_selvalue_t type); -/** Allocates and initializes an expression \c t_selexpr_value. */ -t_selexpr_value * -_gmx_selexpr_create_value_expr(const gmx::SelectionTreeElementPointer &expr); -/** Frees the memory allocated for a chain of values. */ -void -_gmx_selexpr_free_values(t_selexpr_value *value); - /** Propagates the flags for selection elements. */ void _gmx_selelem_update_flags(const gmx::SelectionTreeElementPointer &sel, @@ -217,11 +391,12 @@ _gmx_sel_init_arithmetic(const gmx::SelectionTreeElementPointer &left, gmx::SelectionTreeElementPointer _gmx_sel_init_comparison(const gmx::SelectionTreeElementPointer &left, const gmx::SelectionTreeElementPointer &right, - char *cmpop, void *scanner); + const char *cmpop, void *scanner); /** Creates a gmx::SelectionTreeElement for a keyword expression from the parsed data. */ gmx::SelectionTreeElementPointer _gmx_sel_init_keyword(struct gmx_ana_selmethod_t *method, - t_selexpr_value *args, const char *rpost, void *scanner); + gmx::SelectionParserValueListPointer args, + const char *rpost, void *scanner); /** Creates a gmx::SelectionTreeElement for a method expression from the parsed data. */ gmx::SelectionTreeElementPointer _gmx_sel_init_method(struct gmx_ana_selmethod_t *method, @@ -275,7 +450,8 @@ void _gmx_sel_handle_empty_cmd(void *scanner); /** Process help commands. */ void -_gmx_sel_handle_help_cmd(t_selexpr_value *topic, void *scanner); +_gmx_sel_handle_help_cmd(const gmx::SelectionParserValueListPointer &topic, + void *scanner); /* In params.c */ /** Initializes an array of parameters based on input from the selection parser. */ diff --git a/src/gromacs/selection/position.cpp b/src/gromacs/selection/position.cpp index 8293d9c682..6814f337c2 100644 --- a/src/gromacs/selection/position.cpp +++ b/src/gromacs/selection/position.cpp @@ -135,7 +135,7 @@ gmx_ana_pos_reserve_forces(gmx_ana_pos_t *pos) * \param[in] x Position vector to use. */ void -gmx_ana_pos_init_const(gmx_ana_pos_t *pos, rvec x) +gmx_ana_pos_init_const(gmx_ana_pos_t *pos, const rvec x) { gmx_ana_pos_clear(pos); pos->nr = 1; diff --git a/src/gromacs/selection/position.h b/src/gromacs/selection/position.h index 6ce3f1baf1..6c04ba088c 100644 --- a/src/gromacs/selection/position.h +++ b/src/gromacs/selection/position.h @@ -92,7 +92,7 @@ void gmx_ana_pos_reserve_forces(gmx_ana_pos_t *pos); /** Initializes a \c gmx_ana_pos_t to represent a constant position. */ void -gmx_ana_pos_init_const(gmx_ana_pos_t *pos, rvec x); +gmx_ana_pos_init_const(gmx_ana_pos_t *pos, const rvec x); /** Frees the memory allocated for position storage. */ void gmx_ana_pos_deinit(gmx_ana_pos_t *pos); diff --git a/src/gromacs/selection/sm_same.cpp b/src/gromacs/selection/sm_same.cpp index c2f543e245..9d75e78550 100644 --- a/src/gromacs/selection/sm_same.cpp +++ b/src/gromacs/selection/sm_same.cpp @@ -206,48 +206,48 @@ _gmx_selelem_custom_init_same(gmx_ana_selmethod_t **method, { /* Do nothing if this is not a same method. */ - if (!*method || (*method)->name != sm_same.name) + if (!*method || (*method)->name != sm_same.name || params->empty()) { return 0; } - const gmx::SelectionParserParameter &kwparam = *params->front(); - if (kwparam.nval != 1 || !kwparam.value->hasExpressionValue() - || kwparam.value->expr->type != SEL_EXPRESSION) + const gmx::SelectionParserValueList &kwvalues = params->front()->values(); + if (kwvalues.size() != 1 || !kwvalues.front().hasExpressionValue() + || kwvalues.front().expr->type != SEL_EXPRESSION) { _gmx_selparser_error(scanner, "'same' should be followed by a single keyword"); return -1; } - gmx_ana_selmethod_t *kwmethod = kwparam.value->expr->u.expr.method; + gmx_ana_selmethod_t *kwmethod = kwvalues.front().expr->u.expr.method; if (kwmethod->type == STR_VALUE) { *method = &sm_same_str; } - /* We do custom processing with the second parameter, so remove it from - * the params list, but save the name for later. */ - // TODO: This code should be clearer; possibly easier to do after - // t_selexpr_value is converted to a C++ class. - gmx::SelectionParserParameterPointer &asparam = *(++params->begin()); - std::string pname = asparam->name(); - gmx::SelectionParserParameterList kwparams; - kwparams.push_back(move(asparam)); - kwparams.front()->name_.clear(); - params->resize(1); - - /* Create a second keyword evaluation element for the keyword given as - * the first parameter, evaluating the keyword in the group given by the - * second parameter. */ - gmx::SelectionTreeElementPointer kwelem - = _gmx_sel_init_keyword_evaluator(kwmethod, kwparams, scanner); - // FIXME: Use exceptions. - if (!kwelem) + /* We do custom processing for the "as" parameter. */ + gmx::SelectionParserParameterList::iterator asparam = ++params->begin(); + if (asparam != params->end() && (*asparam)->name() == sm_same.param[1].name) { - return -1; + gmx::SelectionParserParameterList kwparams; + gmx::SelectionParserValueListPointer values( + new gmx::SelectionParserValueList((*asparam)->values())); + kwparams.push_back( + gmx::SelectionParserParameter::create(NULL, move(values))); + + /* Create a second keyword evaluation element for the keyword given as + * the first parameter, evaluating the keyword in the group given by the + * second parameter. */ + gmx::SelectionTreeElementPointer kwelem + = _gmx_sel_init_keyword_evaluator(kwmethod, kwparams, scanner); + // FIXME: Use exceptions. + if (!kwelem) + { + return -1; + } + /* Replace the second parameter with one with a value from \p kwelem. */ + std::string pname = (*asparam)->name(); + *asparam = gmx::SelectionParserParameter::createFromExpression(pname, kwelem); } - /* Replace the second parameter with one with a value from \p kwelem. */ - t_selexpr_value *value = _gmx_selexpr_create_value_expr(kwelem); - params->push_back(gmx::SelectionParserParameter::create(pname, value)); return 0; } diff --git a/src/gromacs/selection/tests/selectionoption.cpp b/src/gromacs/selection/tests/selectionoption.cpp index e5fd8a5eb4..51f15ba9b0 100644 --- a/src/gromacs/selection/tests/selectionoption.cpp +++ b/src/gromacs/selection/tests/selectionoption.cpp @@ -103,8 +103,6 @@ TEST_F(SelectionOptionTest, ParsesSimpleSelection) EXPECT_NO_THROW(assigner.finishOption()); EXPECT_NO_THROW(assigner.finish()); EXPECT_NO_THROW(options_.finish()); - - ASSERT_FALSE(sel.isDynamic()); } @@ -260,7 +258,7 @@ TEST_F(SelectionOptionTest, HandlesDelayedRequiredSelection) EXPECT_NO_THROW(assigner.start()); EXPECT_NO_THROW(assigner.finish()); EXPECT_NO_THROW(options_.finish()); - EXPECT_NO_THROW(manager_.parseRequestedFromString("resname RA RB")); + ASSERT_NO_THROW(manager_.parseRequestedFromString("resname RA RB")); ASSERT_STREQ("resname RA RB", sel.selectionText()); } @@ -295,7 +293,7 @@ TEST_F(SelectionOptionTest, HandlesDelayedOptionalSelection) EXPECT_NO_THROW(assigner.finishOption()); EXPECT_NO_THROW(assigner.finish()); EXPECT_NO_THROW(options_.finish()); - EXPECT_NO_THROW(manager_.parseRequestedFromString("resname RA RB")); + ASSERT_NO_THROW(manager_.parseRequestedFromString("resname RA RB")); ASSERT_STREQ("resname RA RB", sel.selectionText()); } -- 2.11.4.GIT