[stringtemplate-interest] Bug in rest function when applied recursively

John Snyders jjsnyders at rcn.com
Fri Sep 29 15:16:21 PDT 2006


I found a similar problem in passing lists to templates.
Currently anytime the argument passed in to a template is an iterator I can
only use it once. I can see why the iterators are used they work well for
template application.

The bottom line is that I should be able to use an attribute passed to a
template as many times as I want.

Example that shows the bug

listTest(list) ::= <<
   {$list$}
   [$list$]
>>

Here I am trying to use the list argument two times.

Calling listTest as $listTest(list=["a", "b", "c"])$

The output is {abc} []
The expected output is {abc} [abc]

Before I tried to fix the bug with rest by returning a new list rather than
an iterator. This had the disadvantage of making a copy even when in the
context of a template application it wouldn't be needed.

Now I changed ActionEvaluator.argumentAssignment so that it coverts any
iterators to an ArrayList. I put the rest function back the way it was. This
new change works for both rest and lists. I'm still not sure if this is the
best solution but it seems to work. I need to make a similar change to the
case where a single argument is passed to a template without arg=.

Can anyone confirm that this is a bug and if a different solution is needed.

I can make my code change available if anyone is interested.

-John

  -----Original Message-----
  From: John Snyders [mailto:jjsnyders at rcn.com]
  Sent: Thursday, September 28, 2006 3:03 PM
  To: stringtemplate-interest
  Subject: Bug in rest function when applied recursively


  I was thinking about how templates can be called recursively. Just for fun
I decided to try the classic recursive definition of reverse.
      group Reverse;
      reverse(L) ::= <<
      $if(L)$
      $reverse(rest(L))$$first(L)$
      $endif$
      >>

  From another template I called $reverse(list)$ where list is an attribute
created as:
      String myList[] = { "a", "b", "c", "d", "e" };
      st.setAttribute("list", myList);

  The expected result is “edcba”. It is probably not a good idea for a
template to have this kind of logic in it but I wanted to play with
recursion.

  This didn’t work. All it printed was “a”. I tried adding “test $L$,
$first(L)$, $rest(L)$” as the first line of reverse to try to debug. I found
that after the first call first and rest were not working – they returned
nothing. I set a breakpoint in ASTExpr.rest. The rest method will return an
iterator over the collection (I’m using the term collection generally here)
positioned at the second element. It is this iterator and not a collection
that is passed to the template. Now rest is called with the input L being an
iterator. The trouble is that this iterator is already at the end by the
time rest is called again. I’m not exactly sure why that happened but it may
be that the $if(L)$ must evaluate L by iterating. When I added the debugging
that would definitely cause the iterator to stick at the end. The trouble
with an iterator being passed to a template rather than a collection is that
once it is used it can’t be used again! Even $first(L)$ when L is an
iterator will cause problems because it leaves the iterator one position
farther along.

  I changed rest to return a new collection (ArrayList) that contains the
rest of the original collection. After making this change the reverse
template worked perfectly.

  The trouble is that creating a new collection is wasteful. Perhaps there
is a way to determine if a copy of rest is needed rather than just an
iterator. For example just at the point where the iterator is going to be
passed to a template it is copied to a new collection. Are there any other
cases where an iterator should be turned to a collection?

  If Java iterators supported cloning (clone would create a new iterator
over the same colection positioned at the point where the original iterator
was cloned) it may be enough to always return a cloned iterator from rest.
But Java iterators don’t allow cloning.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org:8080/pipermail/stringtemplate-interest/attachments/20060929/5455f646/attachment.html 


More information about the stringtemplate-interest mailing list