/*!
 * \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;
}
Example #2
0
/*!
 * \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;
}
Example #3
0
/*!
 * \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;
}