[stringtemplate-interest] sequences and unique numbers
Udo Borkowski
ub at abego-software.de
Sat Apr 30 03:26:51 PDT 2011
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org/pipermail/stringtemplate-interest/attachments/20110430/ef7f6f69/attachment.html
More information about the stringtemplate-interest
mailing list