[stringtemplate-interest] sequences and unique numbers

Rafael Chaves rafael at alphasimple.com
Sat Apr 30 15:10:53 PDT 2011


That is great, Udo, thanks a lot. You mentioned a unrelated few things
I didn't know before as well (including the fact a parameter default
value can refer to another parameter).

Cheers,

Rafael

On Sat, Apr 30, 2011 at 3:26 AM, Udo Borkowski <ub at abego-software.de> wrote:
> Hi Rafael,
>
> Was something like that ever implemented?
>
> Several times, I guess.
> Notice this is nothing that needs to be added to the StringTemplate
> framework but it is just a way how you write your templates and render them.
> First you need to create the "Counter" class.
> E.g. as Ter suggested:
> public class Counter {
> private int n = 1;
> public String toString() {
> return String.valueOf(n++);
> }
> }
> Then you create an instance of Counter every time you need a sequence of
> unique numbers.
> In the example of Ter
> (http://www.antlr.org/pipermail/stringtemplate-interest/2009-August/002097.html) this
> instance is stored in the attribute "uniq".
> Every time you need a new unique number reference "uniq", but make sure to
> use the "<(…)>" notation to ensure "early evaluation". As you will typically
> want to refer to the unique number you need to store it. In Ter's example
> the parameter "label" is used for this purpose.
>
> if(cond, block, label={end<(uniq)>}) ::= <<
> 	<cond>
> 	brf <label>
> 	<block>
> <label>:
>  >>
>
>
> When I tried to implement this I noticed a problem, at least when using
> StringTemplate v4 (not sure if this also happens for ST 3):
> The parameter label={end<(uniq)>} will not ensure the early evaluation of
> uniq. Only default argument definitions of format
>
>      p = {<(...)>}
>
> will evaluated early.
> So you must split the creation of the unique number from the concatenation
> to the "end…" string. I.e. the template looks like this:
> ifStmt(cond, block, n={<(uniq)>}, label={label<n>}) ::= <<
> <cond>
> brf <label>
> <block>
> <label>:
>>>
> (I also changed the name to "ifStmt" to avoid collision with the "if"
> statement of ST4)
>
> When calling the template like this:
> main(uniq) ::= <<
> <ifStmt("ld a","ld #17")>
> <ifStmt("ld b","ld #42")>
>>>
> It will generate the following output:
> ld a brf label1 ld #17 label1: ld b brf label2 ld #42 label2:
> Hope this helps,
> Udo
>
> P.S.: Here the complete example a test case:
> package org.stringtemplate.v4;
> import org.junit.Assert;
> import org.junit.Test;
> import org.stringtemplate.v4.debug.BaseTest;
> public class UniqueNumberTest extends BaseTest {
> public class Counter {
> private int n = 1;
> public String toString() {
> return String.valueOf(n++);
> }
> }
> /**
> * see
> http://www.antlr.org/pipermail/stringtemplate-interest/2011-April/003458.html
> *
> * @throws Exception
> */
> @Test
> public void testIt() throws Exception {
> String subdir = tmpdir + "/common";
> writeFile(tmpdir, "t.stg",
> "ifStmt(cond, block, n={<(uniq)>}, label={label<n>}) ::= <<\n"
> + "\t<cond>\n\tbrf <label>\n\t<block>\n<label>:\n"
> + ">>"
> + //
> "main(uniq) ::= <<\n"
> + "<ifStmt(\"ld a\",\"ld #17\")>\n\n"
> + "<ifStmt(\"ld b\",\"ld #42\")>\n" + ">>");
> STGroup group = new STGroupFile(tmpdir + "/t.stg");
> ST st = group.getInstanceOf("main");
> st.add("uniq", new Counter());
> String s = st.render();
> Assert.assertEquals(
> "\tld a\n\tbrf label1\n\tld #17\nlabel1:\n\n\tld b\n\tbrf label2\n\tld
> #42\nlabel2:",
> s);
> }
> }
>
>
>
>
>
>
> On 30.04.2011, at 06:11, Rafael Chaves wrote:
>
> I was looking for something similar to this:
>
> http://www.antlr.org/pipermail/stringtemplate-interest/2009-August/002097.html
>
> Was something like that ever implemented?
>
> In my concrete case, I want to generate local variables and avoid
> collisions between them.
>
> Cheers,
>
> Rafael
> _______________________________________________
> stringtemplate-interest mailing list
> stringtemplate-interest at antlr.org
> http://www.antlr.org/mailman/listinfo/stringtemplate-interest
>
>


More information about the stringtemplate-interest mailing list