Track locations for selection parsing products
authorTeemu Murtola <teemu.murtola@gmail.com>
Wed, 5 Nov 2014 19:32:46 +0000 (21:32 +0200)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Tue, 9 Dec 2014 17:43:45 +0000 (18:43 +0100)
SelectionTreeElement and all intermediate structures used for selection
method parameter parsing now track the location in the input string.
By itself, this change does nothing, but it enables the subsequent
change that switches to exceptions to use this information for much
better context information in the error messages.

The location is kept as a SelectionLocation instead of as a string to
avoid spending a lot of memory for these strings with complex
selections: in general, each node in the tree contains the concatenation
of the strings from its child nodes, and there can be quite a few nodes
at the top that all contain have the full selection as their location.

Related to #655.

Change-Id: I7b1a317e043c6ff791b25f5fa357d8166c577fae

src/gromacs/selection/compiler.cpp
src/gromacs/selection/params.cpp
src/gromacs/selection/parser.cpp
src/gromacs/selection/parser.y
src/gromacs/selection/parsetree.cpp
src/gromacs/selection/parsetree.h
src/gromacs/selection/scanner.h
src/gromacs/selection/scanner_internal.cpp
src/gromacs/selection/selelem.cpp
src/gromacs/selection/selelem.h
src/gromacs/selection/sm_keywords.cpp

index 4b696a29ae1095f31e6cd5ac41f0f3a0649e9639..d3a811c316cd93ea7fb77da55506a9570cc2ed6e 100644 (file)
 #include "selmethod.h"
 
 using std::min;
+using gmx::SelectionLocation;
 using gmx::SelectionTreeElement;
 using gmx::SelectionTreeElementPointer;
 
@@ -786,20 +787,21 @@ extract_item_subselections(const SelectionTreeElementPointer &sel,
         /* 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;
@@ -978,7 +980,7 @@ reorder_boolean_static_children(const SelectionTreeElementPointer &sel)
     {
         // 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;
@@ -1942,7 +1944,7 @@ evaluate_boolean_static_part(gmx_sel_evaluate_t                *data,
         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;
index 9c76fe7aea3d034e84c0512489df720e0eafa18e..e1ac68d8289b3224ab9694f4df080b1d82626760 100644 (file)
@@ -59,6 +59,7 @@
 #include "selmethod.h"
 #include "selparam.h"
 
+using gmx::SelectionLocation;
 using gmx::SelectionParserValue;
 using gmx::SelectionParserValueList;
 using gmx::SelectionParserParameter;
@@ -151,7 +152,8 @@ convert_value(SelectionParserValue *value, e_selvalue_t type, void *scanner)
         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 */
@@ -162,7 +164,7 @@ convert_value(SelectionParserValue *value, e_selvalue_t type, void *scanner)
             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;
             }
         }
@@ -559,7 +561,8 @@ parse_values_varnum(const SelectionParserValueList    &values,
      * 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;
@@ -604,7 +607,8 @@ add_child(const SelectionTreeElementPointer &root, gmx_ana_selparam_t *param,
     }
     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;
     }
@@ -1014,20 +1018,21 @@ convert_const_values(SelectionParserValueList *values)
         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(
index 6a2e337a630f74387044e5587e7cb01292d247d8..3c67d419a68e56e5bafcf6b502371a7999ba0e3b 100644 (file)
@@ -2270,7 +2270,7 @@ yyreduce:
                  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);
@@ -2285,7 +2285,7 @@ yyreduce:
                  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);
@@ -2300,7 +2300,7 @@ yyreduce:
                  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);
@@ -2443,7 +2443,7 @@ yyreduce:
     {
                  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);
@@ -2458,7 +2458,7 @@ yyreduce:
     {
                  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);
@@ -2575,7 +2575,7 @@ yyreduce:
     {
                  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);
@@ -2601,7 +2601,7 @@ yyreduce:
 #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;
@@ -2640,7 +2640,7 @@ yyreduce:
 #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;
@@ -2650,7 +2650,7 @@ yyreduce:
 #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;
@@ -2660,7 +2660,7 @@ yyreduce:
 #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;
@@ -2705,7 +2705,7 @@ yyreduce:
     {
                  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;
@@ -2853,7 +2853,7 @@ yyreduce:
 #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;
@@ -2863,7 +2863,7 @@ yyreduce:
 #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;
@@ -2874,7 +2874,7 @@ yyreduce:
     {
                  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;
@@ -2890,7 +2890,7 @@ yyreduce:
 #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;
@@ -2900,7 +2900,7 @@ yyreduce:
 #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;
@@ -2910,7 +2910,7 @@ yyreduce:
 #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;
index d28686f09de13afafe9138ee8b588252e630dfb0..92ac1dfc6d806d907c5cc2bff2d23f7f2173ffaa 100644 (file)
@@ -348,7 +348,7 @@ sel_expr:    NOT sel_expr
                  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);
@@ -359,7 +359,7 @@ sel_expr:    NOT sel_expr
                  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);
@@ -370,7 +370,7 @@ sel_expr:    NOT sel_expr
                  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);
@@ -473,7 +473,7 @@ num_expr:    TOK_INT
              {
                  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;
@@ -484,7 +484,7 @@ num_expr:    TOK_INT
              {
                  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;
@@ -568,7 +568,7 @@ str_expr:    string
              {
                  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;
@@ -593,7 +593,7 @@ str_expr:    string
 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;
              }
 ;
@@ -630,7 +630,7 @@ pos_expr:    KEYWORD_POS OF sel_expr    %prec PARAM_REDUCT
 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;
              }
 ;
@@ -638,7 +638,7 @@ sel_expr:    VARIABLE_GROUP
 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;
              }
 ;
@@ -646,7 +646,7 @@ num_expr:    VARIABLE_NUMERIC
 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;
              }
 ;
@@ -684,7 +684,7 @@ method_param:
              {
                  BEGIN_ACTION;
                  scoped_guard_sfree nameGuard($1);
-                 set($$, SelectionParserParameter::create($1, get($2)));
+                 set($$, SelectionParserParameter::create($1, get($2), @$));
                  END_ACTION;
              }
 ;
@@ -779,20 +779,20 @@ basic_value_item:
              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; }
@@ -802,19 +802,19 @@ value_item_range:
              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;
              }
 ;
index 8b13207cd6a8bb6b398c60547396cd1ab05893a4..fc80abcf7f655b469a8964e83d6207bcf1c93c0e 100644 (file)
 #include "selmethod.h"
 #include "symrec.h"
 
+using gmx::SelectionLocation;
 using gmx::SelectionParserValue;
 using gmx::SelectionParserValueList;
 using gmx::SelectionParserValueListPointer;
@@ -349,15 +350,16 @@ namespace gmx
  * 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));
 }
@@ -367,9 +369,10 @@ SelectionParserValue::SelectionParserValue(
  */
 
 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))
 {
@@ -621,9 +624,11 @@ set_refpos_type(gmx::PositionCalculationCollection *pcc,
 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)
     {
@@ -661,7 +666,9 @@ _gmx_sel_init_comparison(const gmx::SelectionTreeElementPointer &left,
     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;
@@ -673,9 +680,12 @@ _gmx_sel_init_comparison(const gmx::SelectionTreeElementPointer &left,
     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))
     {
@@ -717,7 +727,10 @@ init_keyword_internal(gmx_ana_selmethod_t *method,
                           "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);
 
@@ -735,7 +748,7 @@ init_keyword_internal(gmx_ana_selmethod_t *method,
                                   "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)
         {
@@ -744,7 +757,8 @@ init_keyword_internal(gmx_ana_selmethod_t *method,
         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))
         {
@@ -854,7 +868,9 @@ _gmx_sel_init_method(gmx_ana_selmethod_t                      *method,
     {
         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,
@@ -887,7 +903,9 @@ _gmx_sel_init_modifier(gmx_ana_selmethod_t                      *method,
     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)
@@ -932,7 +950,9 @@ _gmx_sel_init_position(const gmx::SelectionTreeElementPointer &expr,
     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. */
@@ -949,15 +969,18 @@ _gmx_sel_init_position(const gmx::SelectionTreeElementPointer &expr,
 }
 
 /*!
- * \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;
@@ -979,7 +1002,9 @@ SelectionTreeElementPointer
 _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);
@@ -1003,7 +1028,9 @@ _gmx_sel_init_group_by_name(const char *name, yyscan_t scanner)
 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;
@@ -1020,14 +1047,16 @@ _gmx_sel_init_group_by_id(int id, yyscan_t scanner)
 }
 
 /*!
- * \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;
 
@@ -1037,7 +1066,8 @@ _gmx_sel_init_variable_ref(const gmx::SelectionTreeElementPointer &sel)
     }
     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;
@@ -1067,7 +1097,9 @@ _gmx_sel_init_selection(const char                             *name,
                           "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)
     {
@@ -1129,11 +1161,12 @@ _gmx_sel_assign_variable(const char                             *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;
index 00972c372ba3c0647aa25013524bef3e85770349..2b018ca7c236c8b614c48d7963a6fad331ccdc4e 100644 (file)
@@ -139,25 +139,29 @@ class SelectionParserValue
         /*! \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;
@@ -165,25 +169,29 @@ class SelectionParserValue
         /*! \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;
@@ -191,28 +199,34 @@ class SelectionParserValue
         /*! \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); }
 
@@ -255,15 +269,19 @@ class SelectionParserValue
         /*! \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;
@@ -292,27 +310,31 @@ 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.
          *
@@ -321,9 +343,10 @@ class SelectionParserParameter
          * 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.
@@ -341,33 +364,45 @@ class SelectionParserParameter
         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_;
 };
@@ -493,7 +528,7 @@ _gmx_sel_init_position(const gmx::SelectionTreeElementPointer &expr,
 
 /** 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);
@@ -502,7 +537,8 @@ gmx::SelectionTreeElementPointer
 _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
index a058062e21c2aa39db174e69cf85f927bb275099..b49a445365761191e41a857aeeb6744ef17dd2d9 100644 (file)
@@ -110,10 +110,21 @@ const char *
 _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.
  *
index dfd91b1c59ae622b8b9890391eec41eb8303a03f..714a22ad1fae70c4d32f5cc806d9131974f0792d 100644 (file)
@@ -529,6 +529,13 @@ _gmx_sel_lexer_set_current_location(yyscan_t                      scanner,
     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)
 {
index b3b65409799ca6b4d6dacebee73aa82149bb868a..8cca62b067b9f7143ff6a216e04f7ccda8a4e80b 100644 (file)
@@ -132,7 +132,9 @@ _gmx_selelem_boolean_type_str(const gmx::SelectionTreeElement &sel)
 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;
index 08f25e1764e4b572e28950cb9007221131f3d760..c8ba2c0db9dad3d5e2151124fa0702a3715c7d10 100644 (file)
@@ -261,6 +261,13 @@ typedef void (*sel_evalfunc)(struct gmx_sel_evaluate_t         *data,
  */
 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.
@@ -276,7 +283,8 @@ class SelectionTreeElement
         /*! \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
@@ -285,7 +293,7 @@ class SelectionTreeElement
          * 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.
@@ -324,6 +332,9 @@ class SelectionTreeElement
 
         //! 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.
          *
@@ -462,9 +473,16 @@ class SelectionTreeElement
         /*! \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);
 };
index 0081200389bfff4841bdcf0ec905d7e6317be3b4..07d47d972dca66a4a0e30642f291cefac0cd143b 100644 (file)
@@ -765,8 +765,10 @@ init_evaluator_group(gmx_ana_selmethod_t                     *method,
         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
@@ -825,7 +827,8 @@ init_evaluator_pos(gmx_ana_selmethod_t                     *method,
     }
 
     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