#include "selmethod.h"
using std::min;
+using gmx::SelectionLocation;
using gmx::SelectionTreeElement;
using gmx::SelectionTreeElementPointer;
/* The latter check excludes variable references. */
if (child->type == SEL_SUBEXPRREF && child->child->type != SEL_SUBEXPR)
{
+ SelectionLocation location = child->child->location();
/* Create the root element for the subexpression */
if (!root)
{
- root.reset(new SelectionTreeElement(SEL_ROOT));
+ root.reset(new SelectionTreeElement(SEL_ROOT, location));
subexpr = root;
}
else
{
- subexpr->next.reset(new SelectionTreeElement(SEL_ROOT));
+ subexpr->next.reset(new SelectionTreeElement(SEL_ROOT, location));
subexpr = subexpr->next;
}
/* Create the subexpression element and
* move the actual subexpression under the created element. */
- subexpr->child.reset(new SelectionTreeElement(SEL_SUBEXPR));
+ subexpr->child.reset(new SelectionTreeElement(SEL_SUBEXPR, location));
_gmx_selelem_set_vtype(subexpr->child, child->v.type);
subexpr->child->child = child->child;
child->child = subexpr->child;
{
// Add a dummy head element that precedes the first child.
SelectionTreeElementPointer dummy(
- new SelectionTreeElement(SEL_BOOLEAN));
+ new SelectionTreeElement(SEL_BOOLEAN, SelectionLocation::createEmpty()));
dummy->next = sel->child;
SelectionTreeElementPointer prev = dummy;
SelectionTreeElementPointer child = dummy;
child->next.reset();
sel->cdata->evaluate(data, sel, g);
/* Replace the subexpressions with the result */
- child.reset(new SelectionTreeElement(SEL_CONST));
+ child.reset(new SelectionTreeElement(SEL_CONST, SelectionLocation::createEmpty()));
child->flags = SEL_FLAGSSET | SEL_SINGLEVAL | SEL_ALLOCVAL | SEL_ALLOCDATA;
_gmx_selelem_set_vtype(child, GROUP_VALUE);
child->evaluate = NULL;
#include "selmethod.h"
#include "selparam.h"
+using gmx::SelectionLocation;
using gmx::SelectionParserValue;
using gmx::SelectionParserValueList;
using gmx::SelectionParserParameter;
if (value->type == INT_VALUE && type == REAL_VALUE)
{
*value = SelectionParserValue::createRealRange(value->u.i.i1,
- value->u.i.i2);
+ value->u.i.i2,
+ value->location());
return 0;
}
/* Reals that are integer-valued can also be converted */
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);
+ *value = SelectionParserValue::createIntegerRange(i1, i2, value->location());
return 0;
}
}
* other function. */
if (param->val.type == STR_VALUE)
{
- SelectionTreeElementPointer child(new SelectionTreeElement(SEL_CONST));
+ SelectionTreeElementPointer child(
+ new SelectionTreeElement(SEL_CONST, SelectionLocation::createEmpty()));
_gmx_selelem_set_vtype(child, STR_VALUE);
child->setName(param->name);
child->flags &= ~SEL_ALLOCVAL;
}
else
{
- child.reset(new SelectionTreeElement(SEL_SUBEXPRREF));
+ // TODO: Initialize such that it includes the parameter.
+ child.reset(new SelectionTreeElement(SEL_SUBEXPRREF, expr->location()));
_gmx_selelem_set_vtype(child, expr->v.type);
child->child = expr;
}
if (value->hasExpressionValue() && value->expr->v.type != GROUP_VALUE &&
value->expr->type == SEL_CONST)
{
- SelectionTreeElementPointer expr = value->expr;
+ SelectionTreeElementPointer expr = value->expr;
+ const SelectionLocation &location = value->location();
switch (expr->v.type)
{
case INT_VALUE:
- *value = SelectionParserValue::createInteger(expr->v.u.i[0]);
+ *value = SelectionParserValue::createInteger(expr->v.u.i[0], location);
break;
case REAL_VALUE:
- *value = SelectionParserValue::createReal(expr->v.u.r[0]);
+ *value = SelectionParserValue::createReal(expr->v.u.r[0], location);
break;
case STR_VALUE:
- *value = SelectionParserValue::createString(expr->v.u.s[0]);
+ *value = SelectionParserValue::createString(expr->v.u.s[0], location);
break;
case POS_VALUE:
- *value = SelectionParserValue::createPosition(expr->v.u.p->x[0]);
+ *value = SelectionParserValue::createPosition(expr->v.u.p->x[0], location);
break;
default:
GMX_THROW(gmx::InternalError(
BEGIN_ACTION;
SelectionTreeElementPointer arg(get((yyvsp[(2) - (2)].sel)));
SelectionTreeElementPointer sel(
- new SelectionTreeElement(SEL_BOOLEAN));
+ new SelectionTreeElement(SEL_BOOLEAN, (yyloc)));
sel->u.boolt = BOOL_NOT;
sel->child = arg;
set((yyval.sel), sel);
BEGIN_ACTION;
SelectionTreeElementPointer arg1(get((yyvsp[(1) - (3)].sel))), arg2(get((yyvsp[(3) - (3)].sel)));
SelectionTreeElementPointer sel(
- new SelectionTreeElement(SEL_BOOLEAN));
+ new SelectionTreeElement(SEL_BOOLEAN, (yyloc)));
sel->u.boolt = BOOL_AND;
sel->child = arg1; sel->child->next = arg2;
set((yyval.sel), sel);
BEGIN_ACTION;
SelectionTreeElementPointer arg1(get((yyvsp[(1) - (3)].sel))), arg2(get((yyvsp[(3) - (3)].sel)));
SelectionTreeElementPointer sel(
- new SelectionTreeElement(SEL_BOOLEAN));
+ new SelectionTreeElement(SEL_BOOLEAN, (yyloc)));
sel->u.boolt = BOOL_OR;
sel->child = arg1; sel->child->next = arg2;
set((yyval.sel), sel);
{
BEGIN_ACTION;
SelectionTreeElementPointer sel(
- new SelectionTreeElement(SEL_CONST));
+ new SelectionTreeElement(SEL_CONST, (yyloc)));
_gmx_selelem_set_vtype(sel, INT_VALUE);
_gmx_selvalue_reserve(&sel->v, 1);
sel->v.u.i[0] = (yyvsp[(1) - (1)].i);
{
BEGIN_ACTION;
SelectionTreeElementPointer sel(
- new SelectionTreeElement(SEL_CONST));
+ new SelectionTreeElement(SEL_CONST, (yyloc)));
_gmx_selelem_set_vtype(sel, REAL_VALUE);
_gmx_selvalue_reserve(&sel->v, 1);
sel->v.u.r[0] = (yyvsp[(1) - (1)].r);
{
BEGIN_ACTION;
SelectionTreeElementPointer sel(
- new SelectionTreeElement(SEL_CONST));
+ new SelectionTreeElement(SEL_CONST, (yyloc)));
_gmx_selelem_set_vtype(sel, STR_VALUE);
_gmx_selvalue_reserve(&sel->v, 1);
sel->v.u.s[0] = (yyvsp[(1) - (1)].str);
#line 594 "parser.y"
{
BEGIN_ACTION;
- set((yyval.sel), _gmx_sel_init_const_position((yyvsp[(2) - (7)].r), (yyvsp[(4) - (7)].r), (yyvsp[(6) - (7)].r)));
+ set((yyval.sel), _gmx_sel_init_const_position((yyvsp[(2) - (7)].r), (yyvsp[(4) - (7)].r), (yyvsp[(6) - (7)].r), scanner));
END_ACTION;
}
break;
#line 631 "parser.y"
{
BEGIN_ACTION;
- set((yyval.sel), _gmx_sel_init_variable_ref(get((yyvsp[(1) - (1)].sel))));
+ set((yyval.sel), _gmx_sel_init_variable_ref(get((yyvsp[(1) - (1)].sel)), scanner));
END_ACTION;
}
break;
#line 639 "parser.y"
{
BEGIN_ACTION;
- set((yyval.sel), _gmx_sel_init_variable_ref(get((yyvsp[(1) - (1)].sel))));
+ set((yyval.sel), _gmx_sel_init_variable_ref(get((yyvsp[(1) - (1)].sel)), scanner));
END_ACTION;
}
break;
#line 647 "parser.y"
{
BEGIN_ACTION;
- set((yyval.sel), _gmx_sel_init_variable_ref(get((yyvsp[(1) - (1)].sel))));
+ set((yyval.sel), _gmx_sel_init_variable_ref(get((yyvsp[(1) - (1)].sel)), scanner));
END_ACTION;
}
break;
{
BEGIN_ACTION;
scoped_guard_sfree nameGuard((yyvsp[(1) - (2)].str));
- set((yyval.param), SelectionParserParameter::create((yyvsp[(1) - (2)].str), get((yyvsp[(2) - (2)].vlist))));
+ set((yyval.param), SelectionParserParameter::create((yyvsp[(1) - (2)].str), get((yyvsp[(2) - (2)].vlist)), (yyloc)));
END_ACTION;
}
break;
#line 780 "parser.y"
{
BEGIN_ACTION;
- set((yyval.val), SelectionParserValue::createInteger((yyvsp[(1) - (1)].i)));
+ set((yyval.val), SelectionParserValue::createInteger((yyvsp[(1) - (1)].i), (yyloc)));
END_ACTION;
}
break;
#line 786 "parser.y"
{
BEGIN_ACTION;
- set((yyval.val), SelectionParserValue::createReal((yyvsp[(1) - (1)].r)));
+ set((yyval.val), SelectionParserValue::createReal((yyvsp[(1) - (1)].r), (yyloc)));
END_ACTION;
}
break;
{
BEGIN_ACTION;
scoped_guard_sfree stringGuard((yyvsp[(1) - (1)].str));
- set((yyval.val), SelectionParserValue::createString((yyvsp[(1) - (1)].str)));
+ set((yyval.val), SelectionParserValue::createString((yyvsp[(1) - (1)].str), (yyloc)));
END_ACTION;
}
break;
#line 803 "parser.y"
{
BEGIN_ACTION;
- set((yyval.val), SelectionParserValue::createIntegerRange((yyvsp[(1) - (3)].i), (yyvsp[(3) - (3)].i)));
+ set((yyval.val), SelectionParserValue::createIntegerRange((yyvsp[(1) - (3)].i), (yyvsp[(3) - (3)].i), (yyloc)));
END_ACTION;
}
break;
#line 809 "parser.y"
{
BEGIN_ACTION;
- set((yyval.val), SelectionParserValue::createRealRange((yyvsp[(1) - (3)].i), (yyvsp[(3) - (3)].r)));
+ set((yyval.val), SelectionParserValue::createRealRange((yyvsp[(1) - (3)].i), (yyvsp[(3) - (3)].r), (yyloc)));
END_ACTION;
}
break;
#line 815 "parser.y"
{
BEGIN_ACTION;
- set((yyval.val), SelectionParserValue::createRealRange((yyvsp[(1) - (3)].r), (yyvsp[(3) - (3)].r)));
+ set((yyval.val), SelectionParserValue::createRealRange((yyvsp[(1) - (3)].r), (yyvsp[(3) - (3)].r), (yyloc)));
END_ACTION;
}
break;
BEGIN_ACTION;
SelectionTreeElementPointer arg(get($2));
SelectionTreeElementPointer sel(
- new SelectionTreeElement(SEL_BOOLEAN));
+ new SelectionTreeElement(SEL_BOOLEAN, @$));
sel->u.boolt = BOOL_NOT;
sel->child = arg;
set($$, sel);
BEGIN_ACTION;
SelectionTreeElementPointer arg1(get($1)), arg2(get($3));
SelectionTreeElementPointer sel(
- new SelectionTreeElement(SEL_BOOLEAN));
+ new SelectionTreeElement(SEL_BOOLEAN, @$));
sel->u.boolt = BOOL_AND;
sel->child = arg1; sel->child->next = arg2;
set($$, sel);
BEGIN_ACTION;
SelectionTreeElementPointer arg1(get($1)), arg2(get($3));
SelectionTreeElementPointer sel(
- new SelectionTreeElement(SEL_BOOLEAN));
+ new SelectionTreeElement(SEL_BOOLEAN, @$));
sel->u.boolt = BOOL_OR;
sel->child = arg1; sel->child->next = arg2;
set($$, sel);
{
BEGIN_ACTION;
SelectionTreeElementPointer sel(
- new SelectionTreeElement(SEL_CONST));
+ new SelectionTreeElement(SEL_CONST, @$));
_gmx_selelem_set_vtype(sel, INT_VALUE);
_gmx_selvalue_reserve(&sel->v, 1);
sel->v.u.i[0] = $1;
{
BEGIN_ACTION;
SelectionTreeElementPointer sel(
- new SelectionTreeElement(SEL_CONST));
+ new SelectionTreeElement(SEL_CONST, @$));
_gmx_selelem_set_vtype(sel, REAL_VALUE);
_gmx_selvalue_reserve(&sel->v, 1);
sel->v.u.r[0] = $1;
{
BEGIN_ACTION;
SelectionTreeElementPointer sel(
- new SelectionTreeElement(SEL_CONST));
+ new SelectionTreeElement(SEL_CONST, @$));
_gmx_selelem_set_vtype(sel, STR_VALUE);
_gmx_selvalue_reserve(&sel->v, 1);
sel->v.u.s[0] = $1;
pos_expr: '[' number ',' number ',' number ']'
{
BEGIN_ACTION;
- set($$, _gmx_sel_init_const_position($2, $4, $6));
+ set($$, _gmx_sel_init_const_position($2, $4, $6, scanner));
END_ACTION;
}
;
sel_expr: VARIABLE_GROUP
{
BEGIN_ACTION;
- set($$, _gmx_sel_init_variable_ref(get($1)));
+ set($$, _gmx_sel_init_variable_ref(get($1), scanner));
END_ACTION;
}
;
num_expr: VARIABLE_NUMERIC
{
BEGIN_ACTION;
- set($$, _gmx_sel_init_variable_ref(get($1)));
+ set($$, _gmx_sel_init_variable_ref(get($1), scanner));
END_ACTION;
}
;
pos_expr: VARIABLE_POS
{
BEGIN_ACTION;
- set($$, _gmx_sel_init_variable_ref(get($1)));
+ set($$, _gmx_sel_init_variable_ref(get($1), scanner));
END_ACTION;
}
;
{
BEGIN_ACTION;
scoped_guard_sfree nameGuard($1);
- set($$, SelectionParserParameter::create($1, get($2)));
+ set($$, SelectionParserParameter::create($1, get($2), @$));
END_ACTION;
}
;
integer_number %prec PARAM_REDUCT
{
BEGIN_ACTION;
- set($$, SelectionParserValue::createInteger($1));
+ set($$, SelectionParserValue::createInteger($1, @$));
END_ACTION;
}
| real_number %prec PARAM_REDUCT
{
BEGIN_ACTION;
- set($$, SelectionParserValue::createReal($1));
+ set($$, SelectionParserValue::createReal($1, @$));
END_ACTION;
}
| string %prec PARAM_REDUCT
{
BEGIN_ACTION;
scoped_guard_sfree stringGuard($1);
- set($$, SelectionParserValue::createString($1));
+ set($$, SelectionParserValue::createString($1, @$));
END_ACTION;
}
| value_item_range { $$ = $1; }
integer_number TO integer_number
{
BEGIN_ACTION;
- set($$, SelectionParserValue::createIntegerRange($1, $3));
+ set($$, SelectionParserValue::createIntegerRange($1, $3, @$));
END_ACTION;
}
| integer_number TO real_number
{
BEGIN_ACTION;
- set($$, SelectionParserValue::createRealRange($1, $3));
+ set($$, SelectionParserValue::createRealRange($1, $3, @$));
END_ACTION;
}
| real_number TO number
{
BEGIN_ACTION;
- set($$, SelectionParserValue::createRealRange($1, $3));
+ set($$, SelectionParserValue::createRealRange($1, $3, @$));
END_ACTION;
}
;
#include "selmethod.h"
#include "symrec.h"
+using gmx::SelectionLocation;
using gmx::SelectionParserValue;
using gmx::SelectionParserValueList;
using gmx::SelectionParserValueListPointer;
* SelectionParserValue
*/
-SelectionParserValue::SelectionParserValue(e_selvalue_t type)
- : type(type)
+SelectionParserValue::SelectionParserValue(
+ e_selvalue_t type, const SelectionLocation &location)
+ : type(type), location_(location)
{
memset(&u, 0, sizeof(u));
}
SelectionParserValue::SelectionParserValue(
const SelectionTreeElementPointer &expr)
- : type(expr->v.type), expr(expr)
+ : type(expr->v.type), expr(expr), location_(expr->location())
{
memset(&u, 0, sizeof(u));
}
*/
SelectionParserParameter::SelectionParserParameter(
- const char *name,
- SelectionParserValueListPointer values)
- : name_(name != NULL ? name : ""),
+ const char *name,
+ SelectionParserValueListPointer values,
+ const SelectionLocation &location)
+ : name_(name != NULL ? name : ""), location_(location),
values_(values ? move(values)
: SelectionParserValueListPointer(new SelectionParserValueList))
{
gmx::SelectionTreeElementPointer
_gmx_sel_init_arithmetic(const gmx::SelectionTreeElementPointer &left,
const gmx::SelectionTreeElementPointer &right,
- char op, yyscan_t /* scanner */)
+ char op, yyscan_t scanner)
{
- SelectionTreeElementPointer sel(new SelectionTreeElement(SEL_ARITHMETIC));
+ SelectionTreeElementPointer sel(
+ new SelectionTreeElement(
+ SEL_ARITHMETIC, _gmx_sel_lexer_get_current_location(scanner)));
sel->v.type = REAL_VALUE;
switch (op)
{
gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
gmx::MessageStringContext context(errors, formatCurrentErrorContext(scanner));
- SelectionTreeElementPointer sel(new SelectionTreeElement(SEL_EXPRESSION));
+ SelectionTreeElementPointer sel(
+ new SelectionTreeElement(
+ SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner)));
_gmx_selelem_set_method(sel, &sm_compare, scanner);
SelectionParserParameterList params;
name = right->v.type == INT_VALUE ? "int2" : "real2";
params.push_back(SelectionParserParameter::createFromExpression(name, right));
// Create the parameter for the operator.
+ // TODO: Consider whether a proper location is needed.
+ SelectionLocation location(SelectionLocation::createEmpty());
params.push_back(
SelectionParserParameter::create(
- "op", SelectionParserValue::createString(cmpop)));
+ "op", SelectionParserValue::createString(cmpop, location),
+ location));
if (!_gmx_sel_parse_params(params, sel->u.expr.method->nparams,
sel->u.expr.method->param, sel, scanner))
{
"Keyword initialization called with non-keyword method"));
}
- SelectionTreeElementPointer root(new SelectionTreeElement(SEL_EXPRESSION));
+ const SelectionLocation &location = _gmx_sel_lexer_get_current_location(scanner);
+ // TODO: If there are arguments, the location would be better as just the
+ // location of the keyword itself.
+ SelectionTreeElementPointer root(new SelectionTreeElement(SEL_EXPRESSION, location));
SelectionTreeElementPointer child = root;
_gmx_selelem_set_method(child, method, scanner);
"Unknown type for keyword selection"));
}
/* Initialize the selection element */
- root.reset(new SelectionTreeElement(SEL_EXPRESSION));
+ root.reset(new SelectionTreeElement(SEL_EXPRESSION, location));
_gmx_selelem_set_method(root, kwmethod, scanner);
if (method->type == STR_VALUE)
{
SelectionParserParameterList params;
params.push_back(
SelectionParserParameter::createFromExpression(NULL, child));
- params.push_back(SelectionParserParameter::create(NULL, move(args)));
+ params.push_back(
+ SelectionParserParameter::create(NULL, move(args), location));
if (!_gmx_sel_parse_params(params, root->u.expr.method->nparams,
root->u.expr.method->param, root, scanner))
{
{
return SelectionTreeElementPointer();
}
- SelectionTreeElementPointer root(new SelectionTreeElement(SEL_EXPRESSION));
+ SelectionTreeElementPointer root(
+ new SelectionTreeElement(
+ SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner)));
_gmx_selelem_set_method(root, method, scanner);
/* Process the parameters */
if (!_gmx_sel_parse_params(*params, root->u.expr.method->nparams,
gmx::MessageStringContext context(errors, formatCurrentErrorContext(scanner));
_gmx_sel_finish_method(scanner);
- SelectionTreeElementPointer modifier(new SelectionTreeElement(SEL_MODIFIER));
+ SelectionTreeElementPointer modifier(
+ new SelectionTreeElement(
+ SEL_MODIFIER, _gmx_sel_lexer_get_current_location(scanner)));
_gmx_selelem_set_method(modifier, method, scanner);
SelectionTreeElementPointer root;
if (method->type == NO_VALUE)
gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
gmx::MessageStringContext context(errors, formatCurrentErrorContext(scanner));
- SelectionTreeElementPointer root(new SelectionTreeElement(SEL_EXPRESSION));
+ SelectionTreeElementPointer root(
+ new SelectionTreeElement(
+ SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner)));
_gmx_selelem_set_method(root, &sm_keyword_pos, scanner);
_gmx_selelem_set_kwpos_type(root.get(), type);
/* Create the parameters for the parameter parser. */
}
/*!
- * \param[in] x,y,z Coordinates for the position.
+ * \param[in] x,y,z Coordinates for the position.
+ * \param[in] scanner Scanner data structure.
* \returns The creates selection element.
*/
SelectionTreeElementPointer
-_gmx_sel_init_const_position(real x, real y, real z)
+_gmx_sel_init_const_position(real x, real y, real z, yyscan_t scanner)
{
rvec pos;
- SelectionTreeElementPointer sel(new SelectionTreeElement(SEL_CONST));
+ SelectionTreeElementPointer sel(
+ new SelectionTreeElement(
+ SEL_CONST, _gmx_sel_lexer_get_current_location(scanner)));
_gmx_selelem_set_vtype(sel, POS_VALUE);
_gmx_selvalue_reserve(&sel->v, 1);
pos[XX] = x;
_gmx_sel_init_group_by_name(const char *name, yyscan_t scanner)
{
- SelectionTreeElementPointer sel(new SelectionTreeElement(SEL_GROUPREF));
+ SelectionTreeElementPointer sel(
+ new SelectionTreeElement(
+ SEL_GROUPREF, _gmx_sel_lexer_get_current_location(scanner)));
_gmx_selelem_set_vtype(sel, GROUP_VALUE);
sel->setName(gmx::formatString("group \"%s\"", name));
sel->u.gref.name = gmx_strdup(name);
SelectionTreeElementPointer
_gmx_sel_init_group_by_id(int id, yyscan_t scanner)
{
- SelectionTreeElementPointer sel(new SelectionTreeElement(SEL_GROUPREF));
+ SelectionTreeElementPointer sel(
+ new SelectionTreeElement(
+ SEL_GROUPREF, _gmx_sel_lexer_get_current_location(scanner)));
_gmx_selelem_set_vtype(sel, GROUP_VALUE);
sel->setName(gmx::formatString("group %d", id));
sel->u.gref.name = NULL;
}
/*!
- * \param[in,out] sel Value of the variable.
+ * \param[in,out] sel Value of the variable.
+ * \param scanner Scanner data structure.
* \returns The created selection element that references \p sel.
*
* The reference count of \p sel is updated, but no other modifications are
* made.
*/
SelectionTreeElementPointer
-_gmx_sel_init_variable_ref(const gmx::SelectionTreeElementPointer &sel)
+_gmx_sel_init_variable_ref(const gmx::SelectionTreeElementPointer &sel,
+ yyscan_t scanner)
{
SelectionTreeElementPointer ref;
}
else
{
- ref.reset(new SelectionTreeElement(SEL_SUBEXPRREF));
+ ref.reset(new SelectionTreeElement(
+ SEL_SUBEXPRREF, _gmx_sel_lexer_get_current_location(scanner)));
_gmx_selelem_set_vtype(ref, sel->v.type);
ref->setName(sel->name());
ref->child = sel;
"Each selection must evaluate to a position"));
}
- SelectionTreeElementPointer root(new SelectionTreeElement(SEL_ROOT));
+ SelectionTreeElementPointer root(
+ new SelectionTreeElement(
+ SEL_ROOT, _gmx_sel_lexer_get_current_location(scanner)));
root->child = sel;
if (name)
{
}
else
{
+ SelectionLocation location(_gmx_sel_lexer_get_current_location(scanner));
/* Create the root element */
- root.reset(new SelectionTreeElement(SEL_ROOT));
+ root.reset(new SelectionTreeElement(SEL_ROOT, location));
root->setName(name);
/* Create the subexpression element */
- root->child.reset(new SelectionTreeElement(SEL_SUBEXPR));
+ root->child.reset(new SelectionTreeElement(SEL_SUBEXPR, location));
root->child->setName(name);
_gmx_selelem_set_vtype(root->child, expr->v.type);
root->child->child = expr;
/*! \brief
* Allocates and initializes a constant integer value.
*
- * \param[in] value Integer value to assign to the value.
+ * \param[in] value Integer value to assign to the value.
+ * \param[in] location Location of the value.
* \returns The newly created value.
*/
- static SelectionParserValue createInteger(int value)
+ static SelectionParserValue
+ createInteger(int value, const SelectionLocation &location)
{
- SelectionParserValue result(INT_VALUE);
+ SelectionParserValue result(INT_VALUE, location);
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.
+ * \param[in] from Beginning of the range to assign to the value.
+ * \param[in] to End of the range to assign to the value.
+ * \param[in] location Location of the value.
* \returns The newly created value.
*/
- static SelectionParserValue createIntegerRange(int from, int to)
+ static SelectionParserValue
+ createIntegerRange(int from, int to, const SelectionLocation &location)
{
- SelectionParserValue result(INT_VALUE);
+ SelectionParserValue result(INT_VALUE, location);
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.
+ * \param[in] value Floating-point value to assign to the value.
+ * \param[in] location Location of the value.
* \returns The newly created value.
*/
- static SelectionParserValue createReal(real value)
+ static SelectionParserValue
+ createReal(real value, const SelectionLocation &location)
{
- SelectionParserValue result(REAL_VALUE);
+ SelectionParserValue result(REAL_VALUE, location);
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.
+ * \param[in] from Beginning of the range to assign to the value.
+ * \param[in] to End of the range to assign to the value.
+ * \param[in] location Location of the value.
* \returns The newly created value.
*/
- static SelectionParserValue createRealRange(real from, real to)
+ static SelectionParserValue
+ createRealRange(real from, real to, const SelectionLocation &location)
{
- SelectionParserValue result(REAL_VALUE);
+ SelectionParserValue result(REAL_VALUE, location);
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.
+ * \param[in] value String to assign to the value.
+ * \param[in] location Location of the value.
* \returns The newly created value.
*/
- static SelectionParserValue createString(const char *value)
+ static SelectionParserValue
+ createString(const char *value, const SelectionLocation &location)
{
- SelectionParserValue result(STR_VALUE);
+ SelectionParserValue result(STR_VALUE, location);
result.str = value;
return result;
}
/*! \brief
* Allocates and initializes a constant position value.
*
- * \param[in] value Position vector to assign to the value.
+ * \param[in] value Position vector to assign to the value.
+ * \param[in] location Location of the value.
* \returns The newly created value.
*/
- static SelectionParserValue createPosition(rvec value)
+ static SelectionParserValue
+ createPosition(rvec value, const SelectionLocation &location)
{
- SelectionParserValue result(POS_VALUE);
+ SelectionParserValue result(POS_VALUE, location);
copy_rvec(value, result.u.x);
return result;
}
+ //! Returns the location of this value in the parsed selection text.
+ const SelectionLocation &location() const { return location_; }
//! Returns true if the value comes from expression evaluation.
bool hasExpressionValue() const { return static_cast<bool>(expr); }
/*! \brief
* Initializes a new value.
*
- * \param[in] type Type for the new value.
+ * \param[in] type Type for the new value.
+ * \param[in] location Location for the value.
*/
- explicit SelectionParserValue(e_selvalue_t type);
+ SelectionParserValue(e_selvalue_t type, const SelectionLocation &location);
/*! \brief
* Initializes a new expression value.
*
* \param[in] expr Expression for the value.
*/
explicit SelectionParserValue(const gmx::SelectionTreeElementPointer &expr);
+
+ //! Location of the value in the parsed text.
+ SelectionLocation location_;
};
class SelectionParserParameter;
/*! \brief
* Allocates and initializes a parsed method parameter.
*
- * \param[in] name Name for the new parameter (can be NULL).
- * \param[in] values 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.
+ * \param[in] location Location of the parameter.
* \returns Pointer to the newly allocated parameter.
* \throws std::bad_alloc if out of memory.
*/
static SelectionParserParameter
- create(const char *name, SelectionParserValueListPointer values)
+ create(const char *name, SelectionParserValueListPointer values,
+ const SelectionLocation &location)
{
- return SelectionParserParameter(name, move(values));
+ return SelectionParserParameter(name, move(values), location);
}
- //! \copydoc create(const char *, SelectionParserValueListPointer)
+ //! \copydoc create(const char *, SelectionParserValueListPointer, const SelectionLocation &)
static SelectionParserParameter
- create(const std::string &name, SelectionParserValueListPointer values)
+ create(const std::string &name, SelectionParserValueListPointer values,
+ const SelectionLocation &location)
{
- return SelectionParserParameter(name.c_str(), move(values));
+ return SelectionParserParameter(name.c_str(), move(values), location);
}
/*! \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.
+ * \param[in] name Name for the new parameter (can be NULL).
+ * \param[in] value Value for the parameter.
+ * \param[in] location Location of the parameter.
* \returns Pointer to the newly allocated parameter.
* \throws std::bad_alloc if out of memory.
*
* is necessary.
*/
static SelectionParserParameter
- create(const char *name, const SelectionParserValue &value)
+ create(const char *name, const SelectionParserValue &value,
+ const SelectionLocation &location)
{
- return create(name, SelectionParserValue::createList(value));
+ return create(name, SelectionParserValue::createList(value), location);
}
/*! \brief
* Allocates and initializes a parsed method parameter.
createFromExpression(const char *name,
const SelectionTreeElementPointer &expr)
{
- return create(name, SelectionParserValue::createExpr(expr));
+ return create(name, SelectionParserValue::createExpr(expr),
+ expr->location());
}
//! \copydoc createFromExpression(const char *, const SelectionTreeElementPointer &)
static SelectionParserParameter
createFromExpression(const std::string &name,
const SelectionTreeElementPointer &expr)
{
- return create(name.c_str(), SelectionParserValue::createExpr(expr));
+ return create(name.c_str(), SelectionParserValue::createExpr(expr),
+ expr->location());
}
+ //! Returns the name of the parameter (may be empty).
+ const std::string &name() const { return name_; }
+ //! Returns the location of this parameter in the parsed selection text.
+ const SelectionLocation &location() const { return location_; }
+ //! Returns the values for the parameter.
+ const SelectionParserValueList &values() const { return *values_; }
+
+ private:
/*! \brief
* Initializes a parsed method parameter.
*
- * \param[in] name Name for the new parameter (can be NULL).
- * \param[in] values 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.
+ * \param[in] location Location of the parameter.
* \throws std::bad_alloc if out of memory.
*/
- SelectionParserParameter(const char *name,
- SelectionParserValueListPointer values);
-
- //! 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_; }
+ SelectionParserParameter(const char *name,
+ SelectionParserValueListPointer values,
+ const SelectionLocation &location);
//! Name of the parameter.
std::string name_;
+ //! Location of the parameter in the parsed text.
+ SelectionLocation location_;
+
+ // TODO: Make private, there is only one direct user.
+ public:
//! Values for this parameter.
SelectionParserValueListPointer values_;
};
/** Creates a gmx::SelectionTreeElement for a constant position. */
gmx::SelectionTreeElementPointer
-_gmx_sel_init_const_position(real x, real y, real z);
+_gmx_sel_init_const_position(real x, real y, real z, void *scanner);
/** Creates a gmx::SelectionTreeElement for a index group expression using group name. */
gmx::SelectionTreeElementPointer
_gmx_sel_init_group_by_name(const char *name, void *scanner);
_gmx_sel_init_group_by_id(int id, void *scanner);
/** Creates a gmx::SelectionTreeElement for a variable reference */
gmx::SelectionTreeElementPointer
-_gmx_sel_init_variable_ref(const gmx::SelectionTreeElementPointer &sel);
+_gmx_sel_init_variable_ref(const gmx::SelectionTreeElementPointer &sel,
+ void *scanner);
/** Creates a root gmx::SelectionTreeElement for a selection. */
gmx::SelectionTreeElementPointer
_gmx_sel_lexer_pselstr(yyscan_t scanner);
/*! \brief
* Sets the current parser context location.
+ *
+ * This location is set while Bison reductions are being processed, and
+ * identifies the location of the current rule/reduction.
*/
void
_gmx_sel_lexer_set_current_location(yyscan_t scanner,
const gmx::SelectionLocation &location);
+/*! \brief
+ * Returns the current parser context location.
+ *
+ * This returns the location last set with
+ * _gmx_sel_lexer_set_current_location().
+ */
+const gmx::SelectionLocation &
+_gmx_sel_lexer_get_current_location(yyscan_t scanner);
/*! \brief
* Returns the selection text for the current parser context.
*
state->currentLocation = location;
}
+const gmx::SelectionLocation &
+_gmx_sel_lexer_get_current_location(yyscan_t scanner)
+{
+ gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner);
+ return state->currentLocation;
+}
+
std::string
_gmx_sel_lexer_get_current_text(yyscan_t scanner)
{
namespace gmx
{
-SelectionTreeElement::SelectionTreeElement(e_selelem_t type)
+SelectionTreeElement::SelectionTreeElement(e_selelem_t type,
+ const SelectionLocation &location)
+ : location_(location)
{
this->type = type;
this->flags = (type != SEL_ROOT) ? SEL_ALLOCVAL : 0;
*/
struct SelectionLocation
{
+ //! Returns an empty location.
+ static SelectionLocation createEmpty()
+ {
+ SelectionLocation empty = {0, 0};
+ return empty;
+ }
+
//! Start index of the string where this element has been parsed from.
int startIndex;
//! End index of the string where this element has been parsed from.
/*! \brief
* Allocates memory and performs common initialization.
*
- * \param[in] type Type of selection element to create.
+ * \param[in] type Type of selection element to create.
+ * \param[in] location Location of the element.
*
* \a type is set to \p type,
* \a v::type is set to \ref GROUP_VALUE for boolean and comparison
* is also set for \ref SEL_BOOLEAN elements).
* All the pointers are set to NULL.
*/
- explicit SelectionTreeElement(e_selelem_t type);
+ SelectionTreeElement(e_selelem_t type, const SelectionLocation &location);
~SelectionTreeElement();
//! Frees the memory allocated for the \a v union.
//! Returns the name of the element.
const std::string &name() const { return name_; }
+ //! Returns the location of the element.
+ const SelectionLocation &location() const { return location_; }
+
/*! \brief
* Sets the name of the element.
*
/*! \brief
* Name of the element.
*
- * This field is only used for informative purposes.
+ * This field is only used for diagnostic purposes.
*/
std::string name_;
+ /*! \brief
+ * Location of the element in the selection text.
+ *
+ * This field is only used for diagnostic purposes (including error
+ * messages).
+ */
+ SelectionLocation location_;
GMX_DISALLOW_COPY_AND_ASSIGN(SelectionTreeElement);
};
GMX_THROW(gmx::InvalidInputError(message));
}
+ // TODO: For same ... as ..., some other location could be more intuitive.
gmx::SelectionTreeElementPointer sel(
- new gmx::SelectionTreeElement(SEL_EXPRESSION));
+ new gmx::SelectionTreeElement(
+ SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner)));
_gmx_selelem_set_method(sel, method, scanner);
t_methoddata_kweval *data
}
gmx::SelectionTreeElementPointer sel(
- new gmx::SelectionTreeElement(SEL_EXPRESSION));
+ new gmx::SelectionTreeElement(
+ SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner)));
_gmx_selelem_set_method(sel, method, scanner);
t_methoddata_kweval *data