[stringtemplate-interest] Strange tail-recursive behaviour

Terence Parr parrt at cs.usfca.edu
Wed Oct 12 11:19:20 PDT 2005


Hi Laurent,

This definitely looks like a bug to me.  You have

> TRUE:<x>
> TRUE:<x>

when x is B it prints

TRUE:B
TRUE:

I just figured it out too.  You are passing in rest(x) which creates  
an iterator.  When you ref it again, the iterator has not been  
reset!  Ack!

Adding as a bug unit test:

     public void testRepeatedRestOpAsArg() throws Exception {
         String templates =
                 "group test;" +newline+
                 "root(names) ::= \"$other(rest(names))$\""+newline+
                 "other(x) ::= \"$x$, $x$\""+newline
                 ;
         StringTemplateGroup group =
                 new StringTemplateGroup(new StringReader(templates));
         StringTemplate e = group.getInstanceOf("root");
         e.setAttribute("names", "Ter");
         e.setAttribute("names", "Tom");
         String expecting = "Tom, Tom";
         assertEqual(e.toString(), expecting);
     }

Passing an operation result as an attribute seems to reuse the same  
iterator object. Hmm...

Thanks!

Ter

On Oct 12, 2005, at 6:52 AM, VAUCHER Laurent wrote:

>   Hi,
>
>   I'm currently trying StringTemplate (v2.2 downloaded yesterday  
> oct 11)
> and trying a kind of tail-recursive template, I stumbled upon the
> following behaviour.
>
>   I have a template group file that reads :
> --- "mytest/main.stg" ----------------------
> group main;
>
> /* Root template  */
> root(place) ::= <<
>
> <namestail(place)>
>
>
>>>
>>>
>
> /* Tail template  */
> namestail(x) ::= <<
>
> <if(x)>
> ++++
> TRUE:<x>
> TRUE:<x>
> first(PLACE)=<first(x)>
> rest(PLACE)=<rest(x)>
> TAIL CALL:
> <namestail(x=rest(x))>
> <else>
> -----
> FALSE:<x>
> <endif>
>
>
>>>
>>>
> ---------------------------------------------
>
>
>
>   and a simple driver class
>
>
>
>
> ----- "Main.java" ---------------------------
> import java.io.FileNotFoundException;
> import java.io.FileReader;
> import java.text.SimpleDateFormat;
> import java.util.Date;
>
> import org.antlr.stringtemplate.StringTemplate;
> import org.antlr.stringtemplate.StringTemplateGroup;
> import org.antlr.stringtemplate.language.AngleBracketTemplateLexer;
>
> public class Main {
>
>   /**
>    * @param args
>    */
>   public static void main(String[] args) {
>     System.out.println(new SimpleDateFormat().format(new Date()));
>
>     try {
>       FileReader reader = new FileReader("src/mytest/main.stg");
>       StringTemplateGroup stg = new StringTemplateGroup(reader,
>           AngleBracketTemplateLexer.class);
>
>       StringTemplate firstST = stg.getInstanceOf("root");
>       firstST.setAttribute("place", "A");
>       firstST.setAttribute("place", "B");
>
>       System.out.println("Generated [" + firstST.toString() + "]");
>     } catch (FileNotFoundException eFNFE) {
>       eFNFE.printStackTrace(System.err);
>     }
>   }
> }
> --------------------------------------------
>
>
>    And the output is :
>
>
> ------------- output -----------------------
> 12/10/05 15:37
> Generated [
>
> ++++
> TRUE:AB
> TRUE:AB
> first(PLACE)=A
> rest(PLACE)=B
> TAIL CALL:
>
> ++++
> TRUE:B
> TRUE:
> first(PLACE)=
> rest(PLACE)=
> TAIL CALL:
>
> -----
> FALSE:
> ]
> --------------------------------------------
>
>   What I find annoying is the inner call to namestail : the value of x
> changes from a line to the next. The first "TRUE:<x>" yields "TRUE:b",
> the second "TRUE:" as if the value had been swallowed by the first  
> <x>.
> As you can see, the outer invocation of namestail does not seem
> afflicted...
>
>   Is there something I am missing (dynamic scoping can be tricky, I
> know) ?
>
>
>
> Laurent.
>
> _______________________________________________
> stringtemplate-interest mailing list
> stringtemplate-interest at antlr.org
> http://www.antlr.org:8080/mailman/listinfo/stringtemplate-interest
>



More information about the stringtemplate-interest mailing list