Rascal is rooted in term rewriting. Does it have built-in support for term/node position as commonly defined in term rewriting so that I can query for the position of a sub-term inside a term or the other way around?
1 Answers
I don't believe explicit positions are commonly defined in the semantics of term rewriting, but nevertheless Rascal defines all kinds of operations on terms such that positions are explicit or can be made explicit. Please also have a look at he manuals at http://www.rascal-mpl.org
The main operation on terms is pattern matching using normal first order congruence, deep (higher order) match, negative match, disjunctive match, etc:
if (and(and(_, _), _) := and(and(true(),false()), false())) // pattern match operator :=
println("yes!");
and(true(), b) = b; // function definition, aka rewrite rule
and(false(), _) = false();
[ a | and(a,b) <- booleanList]; // comprehension with pattern as filter on a generator
innermost visit (t) { // explicit automated traversal with strategies
case and(a,b) => or(a,b)
}
b.leftHandSide = true(); // assign new child term to the leftHandSide field of the term assigned to the b variable (non-destructively, you get a new b)
b[0] = false(); // same but to the anonymous first child.
Then there are the normal projection operators, index on the children term[0]
and child-by-name: term.myChildName
if there was a many sorted term signature defined using field labels.
if you want to know at which position a sub-child is, I would perhaps write it as such:
int getPos(node t, value child) = [*pre, child, *_] := getChildren(t) ? size(pre) : -1;
but there are other ways of achieving the same.
Rascal does not have pointers to the parents of a term.

- 6,393
- 1
- 15
- 26
-
Thanks for the answer. I am aware that accessing a sub-term can be achieved by visitors. What I was asking is whether there exists support for finding the position (maybe I should use _path_ because position is defined to be file position in Rascal, also as your `getPos` shows) of a sub-term, say a function `myGetPos` such that `myGetPos(and(and(true(), false()), false()), true()) == [0, 1]`, with `0` being the position of the root node. – day Apr 11 '14 at 19:29
-
ah yes! a path resonates with me. There is no direct support, let me think about it. What is the reason that you need it? – Jurgen Vinju Apr 14 '14 at 10:25
-
For example, when I want to trace an identifier (or maybe any sub-term) through several program transformations. I know there is string origin. But it is tightly bound to the original text. In particular, along the transformation chain, no extra info could be accumulated onto it to form a trace of the identifier, unless you first write an intermediate AST out to a temporary text and index this file to obtain the new location info. (I am not sure even if you can store the obtained info.) This is unacceptable. I feel the only unique meta-data about an identifier is its path in the AST. – day Apr 14 '14 at 11:55
-
I will also complain to Tijs. – day Apr 14 '14 at 11:57
-
You might use the library module `Traversal`, and in particular `getTraversalContextNodes()`, which in the context of a `visit` will give you a list of all the current parents. – Jurgen Vinju Apr 15 '14 at 20:58
-
Hmm, it is not documented? Where can I find more info about this module and the function in particular? – day Apr 16 '14 at 11:44
-
It's undocumented. Give it a try :-) – Jurgen Vinju Apr 17 '14 at 17:59