/*! * \param[in] method Method to use for initialization. * \param[in] params Pointer to the first parameter. * \param[in] rpost Reference position type to use (NULL = default). * \param[in] scanner Scanner data structure. * \returns The created selection element. * * This function handles the creation of a gmx::SelectionTreeElement object for * selection methods that take parameters. * * Part of the behavior of the \c same selection keyword is hardcoded into * this function (or rather, into _gmx_selelem_custom_init_same()) to allow the * use of any keyword in \c "same KEYWORD as" without requiring special * handling somewhere else (or sacrificing the simple syntax). */ SelectionTreeElementPointer _gmx_sel_init_method(gmx_ana_selmethod_t *method, gmx::SelectionParserParameterListPointer params, const char *rpost, yyscan_t scanner) { gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); int rc; gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner); char buf[128]; sprintf(buf, "In keyword '%s'", method->name); gmx::MessageStringContext context(errors, buf); _gmx_sel_finish_method(scanner); /* The "same" keyword needs some custom massaging of the parameters. */ rc = _gmx_selelem_custom_init_same(&method, params, scanner); if (rc != 0) { return SelectionTreeElementPointer(); } SelectionTreeElementPointer root(new SelectionTreeElement(SEL_EXPRESSION)); _gmx_selelem_set_method(root, method, scanner); /* Process the parameters */ if (!_gmx_sel_parse_params(*params, root->u.expr.method->nparams, root->u.expr.method->param, root, scanner)) { return SelectionTreeElementPointer(); } set_refpos_type(&sc->pcc, root, rpost, scanner); return root; }
/*! * \param[in] id Zero-based index number of the group to extract. * \param[in] scanner Scanner data structure. * \returns The created constant selection element, or NULL if no matching * index group found. */ SelectionTreeElementPointer _gmx_sel_init_group_by_id(int id, yyscan_t scanner) { gmx_ana_indexgrps_t *grps = _gmx_sel_lexer_indexgrps(scanner); if (!_gmx_sel_lexer_has_groups_set(scanner)) { SelectionTreeElementPointer sel(new SelectionTreeElement(SEL_GROUPREF)); _gmx_selelem_set_vtype(sel, GROUP_VALUE); sel->u.gref.name = NULL; sel->u.gref.id = id; return sel; } if (!grps) { _gmx_selparser_error(scanner, "No index groups set; cannot match 'group %d'", id); return SelectionTreeElementPointer(); } SelectionTreeElementPointer sel(new SelectionTreeElement(SEL_CONST)); _gmx_selelem_set_vtype(sel, GROUP_VALUE); std::string foundName; if (!gmx_ana_indexgrps_extract(&sel->u.cgrp, &foundName, grps, id)) { _gmx_selparser_error(scanner, "Cannot match 'group %d'", id); return SelectionTreeElementPointer(); } sel->setName(foundName); return sel; }
/*! * \param[in] name Name of an index group to search for. * \param[in] scanner Scanner data structure. * \returns The created constant selection element, or NULL if no matching * index group found. * * See gmx_ana_indexgrps_find() for information on how \p name is matched * against the index groups. */ SelectionTreeElementPointer _gmx_sel_init_group_by_name(const char *name, yyscan_t scanner) { gmx_ana_indexgrps_t *grps = _gmx_sel_lexer_indexgrps(scanner); if (!_gmx_sel_lexer_has_groups_set(scanner)) { SelectionTreeElementPointer sel(new SelectionTreeElement(SEL_GROUPREF)); _gmx_selelem_set_vtype(sel, GROUP_VALUE); sel->setName(name); sel->u.gref.name = strdup(name); sel->u.gref.id = -1; return sel; } if (!grps) { _gmx_selparser_error(scanner, "No index groups set; cannot match 'group %s'", name); return SelectionTreeElementPointer(); } SelectionTreeElementPointer sel(new SelectionTreeElement(SEL_CONST)); _gmx_selelem_set_vtype(sel, GROUP_VALUE); std::string foundName; if (!gmx_ana_indexgrps_find(&sel->u.cgrp, &foundName, grps, name)) { _gmx_selparser_error(scanner, "Cannot match 'group %s'", name); return SelectionTreeElementPointer(); } sel->setName(foundName); return sel; }
/*! * \param[in] left Selection element for the left hand side. * \param[in] right Selection element for the right hand side. * \param[in] cmpop String representation of the comparison operator. * \param[in] scanner Scanner data structure. * \returns The created selection element. * * This function handles the creation of a gmx::SelectionTreeElement object for * comparison expressions. */ SelectionTreeElementPointer _gmx_sel_init_comparison(const gmx::SelectionTreeElementPointer &left, const gmx::SelectionTreeElementPointer &right, const char *cmpop, yyscan_t scanner) { gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner); gmx::MessageStringContext context(errors, "In comparison initialization"); SelectionTreeElementPointer sel(new SelectionTreeElement(SEL_EXPRESSION)); _gmx_selelem_set_method(sel, &sm_compare, scanner); SelectionParserParameterList params; const char *name; // Create the parameter for the left expression. name = left->v.type == INT_VALUE ? "int1" : "real1"; params.push_back(SelectionParserParameter::createFromExpression(name, left)); // Create the parameter for the right expression. name = right->v.type == INT_VALUE ? "int2" : "real2"; 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)) { return SelectionTreeElementPointer(); } return sel; }
/*! \brief * Implementation method for keyword expression creation. * * \param[in] method Method to use. * \param[in] matchType String matching type (only used if \p method is * a string keyword and \p args is not empty. * \param[in] args Pointer to the first argument. * \param[in] rpost Reference position type to use (NULL = default). * \param[in] scanner Scanner data structure. * \returns The created selection element. * * This function handles the creation of a gmx::SelectionTreeElement object for * selection methods that do not take parameters. */ static SelectionTreeElementPointer init_keyword_internal(gmx_ana_selmethod_t *method, gmx::SelectionStringMatchType matchType, SelectionParserValueListPointer args, const char *rpost, yyscan_t scanner) { gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner); char buf[128]; sprintf(buf, "In keyword '%s'", method->name); gmx::MessageStringContext context(errors, buf); if (method->nparams > 0) { // TODO: Would assert be better? GMX_THROW(gmx::InternalError( "Keyword initialization called with non-keyword method")); } SelectionTreeElementPointer root(new SelectionTreeElement(SEL_EXPRESSION)); SelectionTreeElementPointer child = root; _gmx_selelem_set_method(child, method, scanner); /* Initialize the evaluation of keyword matching if values are provided */ if (args) { gmx_ana_selmethod_t *kwmethod; switch (method->type) { case INT_VALUE: kwmethod = &sm_keyword_int; break; case REAL_VALUE: kwmethod = &sm_keyword_real; break; case STR_VALUE: kwmethod = &sm_keyword_str; break; default: GMX_THROW(gmx::InternalError( "Unknown type for keyword selection")); } /* Initialize the selection element */ root.reset(new SelectionTreeElement(SEL_EXPRESSION)); _gmx_selelem_set_method(root, kwmethod, scanner); if (method->type == STR_VALUE) { _gmx_selelem_set_kwstr_match_type(root, matchType); } SelectionParserParameterList params; 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)) { return SelectionTreeElementPointer(); } } set_refpos_type(&sc->pcc, child, rpost, scanner); return root; }
/*! * \param[in] method Modifier to use for initialization. * \param[in] params Pointer to the first parameter. * \param[in] sel Selection element that the modifier should act on. * \param[in] scanner Scanner data structure. * \returns The created selection element. * * This function handles the creation of a gmx::SelectionTreeElement object for * selection modifiers. */ SelectionTreeElementPointer _gmx_sel_init_modifier(gmx_ana_selmethod_t *method, gmx::SelectionParserParameterListPointer params, const gmx::SelectionTreeElementPointer &sel, yyscan_t scanner) { gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner); char buf[128]; sprintf(buf, "In keyword '%s'", method->name); gmx::MessageStringContext context(errors, buf); _gmx_sel_finish_method(scanner); SelectionTreeElementPointer modifier(new SelectionTreeElement(SEL_MODIFIER)); _gmx_selelem_set_method(modifier, method, scanner); SelectionTreeElementPointer root; if (method->type == NO_VALUE) { SelectionTreeElementPointer child = sel; while (child->next) { child = child->next; } child->next = modifier; root = sel; } else { params->push_front( SelectionParserParameter::createFromExpression(NULL, sel)); root = modifier; } /* Process the parameters */ if (!_gmx_sel_parse_params(*params, modifier->u.expr.method->nparams, modifier->u.expr.method->param, modifier, scanner)) { return SelectionTreeElementPointer(); } return root; }
/*! * \param[in] expr Input selection element for the position calculation. * \param[in] type Reference position type or NULL for default. * \param[in] scanner Scanner data structure. * \returns The created selection element. * * This function handles the creation of a gmx::SelectionTreeElement object for * evaluation of reference positions. */ SelectionTreeElementPointer _gmx_sel_init_position(const gmx::SelectionTreeElementPointer &expr, const char *type, yyscan_t scanner) { gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner); char buf[128]; sprintf(buf, "In position evaluation"); gmx::MessageStringContext context(errors, buf); SelectionTreeElementPointer root(new SelectionTreeElement(SEL_EXPRESSION)); _gmx_selelem_set_method(root, &sm_keyword_pos, scanner); _gmx_selelem_set_kwpos_type(root.get(), type); /* Create the parameters for the parameter parser. */ SelectionParserParameterList params; 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)) { return SelectionTreeElementPointer(); } return root; }