/*! * \param scanner Scanner data structure. * \param[in] sel The selection element that evaluates the selection. * \returns The created root selection element. * * This function handles the creation of root (\ref SEL_ROOT) \c t_selelem * objects for selections. */ t_selelem * _gmx_sel_init_selection(gmx_sel_lexer_t *scanner, t_selelem *sel) { gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); t_selelem *root; int rc; if (sel->v.type != POS_VALUE) { gmx_bug("each selection must evaluate to a position"); /* FIXME: Better handling of this error */ return NULL; } root = _gmx_selelem_create(SEL_ROOT); root->child = sel; /* Update the flags */ rc = _gmx_selelem_update_flags(root); if (rc != 0) { _gmx_selelem_free(root); return NULL; } /* Print out some information if the parser is interactive */ if (_gmx_sel_is_lexer_interactive(scanner)) { /* TODO: It would be nice to print the whole selection here */ fprintf(stderr, "Selection parsed\n"); } return root; }
void SelectionCollection::Impl::runParser(yyscan_t scanner, int maxnr, std::vector<Selection *> *output) { gmx_ana_selcollection_t *sc = &_sc; GMX_ASSERT(sc == _gmx_sel_lexer_selcollection(scanner), "Incorrectly initialized lexer"); MessageStringCollector errors; _gmx_sel_set_lexer_error_reporter(scanner, &errors); int oldCount = sc->sel.size(); int bOk = !_gmx_sel_yybparse(scanner); _gmx_sel_free_lexer(scanner); int nr = sc->sel.size() - oldCount; if (maxnr > 0 && nr != maxnr) { bOk = false; errors.append("Too few selections provided"); } if (bOk) { SelectionList::const_iterator i; for (i = _sc.sel.begin() + oldCount; i != _sc.sel.end(); ++i) { output->push_back(*i); } } if (!bOk || !errors.isEmpty()) { GMX_ASSERT(!bOk && !errors.isEmpty(), "Inconsistent error reporting"); GMX_THROW(InvalidInputError(errors.toString())); } }
/*! * \param scanner Scanner data structure. * \param[in] name Name of the variable (should not be freed after this * function). * \param[in] expr The selection element that evaluates the variable. * \returns The created root selection element. * * This function handles the creation of root \c t_selelem objects for * variable assignments. A \ref SEL_ROOT element and a \ref SEL_SUBEXPR * element are both created. */ t_selelem * _gmx_sel_assign_variable(gmx_sel_lexer_t *scanner, char *name, t_selelem *expr) { gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); t_selelem *root; int rc; rc = _gmx_selelem_update_flags(expr); if (rc != 0) { sfree(name); _gmx_selelem_free(expr); return NULL; } /* Check if this is a constant non-group value */ if (expr->type == SEL_CONST && expr->v.type != GROUP_VALUE) { /* If so, just assign the constant value to the variable */ if (!_gmx_sel_add_var_symbol(sc->symtab, name, expr)) { _gmx_selelem_free(expr); sfree(name); return NULL; } _gmx_selelem_free(expr); if (_gmx_sel_is_lexer_interactive(scanner)) { fprintf(stderr, "Variable '%s' parsed\n", name); } sfree(name); return NULL; } /* Check if we are assigning a variable to another variable */ if (expr->type == SEL_SUBEXPRREF) { /* If so, make a simple alias */ if (!_gmx_sel_add_var_symbol(sc->symtab, name, expr->child)) { _gmx_selelem_free(expr); sfree(name); return NULL; } _gmx_selelem_free(expr); if (_gmx_sel_is_lexer_interactive(scanner)) { fprintf(stderr, "Variable '%s' parsed\n", name); } sfree(name); return NULL; } /* Create the root element */ root = _gmx_selelem_create(SEL_ROOT); root->name = name; root->u.cgrp.name = name; /* Create the subexpression element */ root->child = _gmx_selelem_create(SEL_SUBEXPR); _gmx_selelem_set_vtype(root->child, expr->v.type); root->child->name = name; root->child->child = expr; /* Update flags */ rc = _gmx_selelem_update_flags(root); if (rc != 0) { _gmx_selelem_free(root); return NULL; } /* Add the variable to the symbol table */ if (!_gmx_sel_add_var_symbol(sc->symtab, name, root->child)) { _gmx_selelem_free(root); return NULL; } if (_gmx_sel_is_lexer_interactive(scanner)) { fprintf(stderr, "Variable '%s' parsed\n", name); } return root; }