Nesting one template inside another with StringTemplate 4 - template-engine

I am having problem understanding how to nest another template inside another. For example, I have 3 templates: application.stg, wrapper.stg and core.stg.
core.stg:
page(data1, data2) ::= <<
<h1>$data1$</h1>
<h1>$data2$</h1>
>>
wrapper.stg:
page(data3, data4) ::= <<
<h1>$data3$</h1>
<!----- CORE.STG GOES HERE ------->
<h1>$data4$</h1>
>>
application.stg:
page(data7, data8) ::= <<
<h1>$data7$</h1>
<!----- WRAPPER.STG GOES HERE ------->
<h1>$data8$</h1>
>>
The documentation seems to hint that this is possible (Conditional Subtemplate section), but sorry, I could not figure out the syntax at all. Please help me out.

You can create a whole file with every template and make sure you set the .stg extension to it.
Then create a TemplateGroupFile object and set the properties data7 and data8 and tell it to start in the application template.
core(data1, data2) ::= <<
<h1>$data1$</h1>
<h1>$data2$</h1>
>>
wrapper(data3, data4) ::= <<
<h1>$data3$</h1>
core(data3,data4)
<h1>$data4$</h1>
>>
application(data7, data8) ::= <<
<h1>$data7$</h1>
wrapper(data7,data8)
<h1>$data8$</h1>
>>
This is the C# code
TemplateGroupFile grp = new TemplateGroupFile(Template);
Template page_tpl = grp.GetInstanceOf(GroupName);
GroupName = "application";
page_tpl.Add("data7", yourData);
page_tpl.Add("data8", moreOfYourData);
File.WriteAllText(Path.Combine(dir, Path.GetFileName(outputFile)), page_tpl.Render());

Related

How to implement case insensitive lexical parser in Golang using gocc?

I need to build a lexical analyzer using Gocc, however no option to ignore case is mentioned in the documentation and I haven't been able to find anything related. Anyone have any idea how it can be done or should I use another tool?
/* Lexical part */
_digit : '0'-'9' ;
int64 : '1'-'9' {_digit} ;
switch: 's''w''i''t''c''h';
while: 'w''h''i''l''e';
!whitespace : ' ' | '\t' | '\n' | '\r' ;
/* Syntax part */
<<
import(
"github.com/goccmack/gocc/example/calc/token"
"github.com/goccmack/gocc/example/calc/util"
)
>>
Calc : Expr;
Expr :
Expr "+" Term << $0.(int64) + $2.(int64), nil >>
| Term
;
Term :
Term "*" Factor << $0.(int64) * $2.(int64), nil >>
| Factor
;
Factor :
"(" Expr ")" << $1, nil >>
| int64 << util.IntValue($0.(*token.Token).Lit) >>
;
For example, for "switch", I want to recognize no matter if it is uppercase or lowercase, but without having to type all the combinations. In Bison there is the option % option caseless, in Gocc is there one?
Looking through the docs for that product, I don't see any option for making character literals case-insensitive, nor do I see any way to write a character class, as in pretty well every regex engine and scanner generator. But nothing other than tedium, readability and style stops you from writing
switch: ('s'|'S')('w'|'W')('i'|'I')('t'|'T')('c'|'C')('h'|'H');
while: ('w'|'W')('h'|'H')('i'|'I')('l'|'L')('e'|'E');
(That's derived from the old way of doing it in lex without case-insensitivity, which uses character classes to make it quite a bit more readable:
[sS][wW][iI][tT][cC][hH] return T_SWITCH;
[wW][hH][iI][lL][eE] return T_WHILE;
You can come closer to the former by defining 26 patterns:
_a: 'a'|'A';
_b: 'b'|'B';
_c: 'c'|'C';
_d: 'd'|'D';
_e: 'e'|'E';
_f: 'f'|'F';
_g: 'g'|'G';
_h: 'h'|'H';
_i: 'i'|'I';
_j: 'j'|'J';
_k: 'k'|'K';
_l: 'l'|'L';
_m: 'm'|'M';
_n: 'n'|'N';
_o: 'o'|'O';
_p: 'p'|'P';
_q: 'q'|'Q';
_r: 'r'|'R';
_s: 's'|'S';
_t: 't'|'T';
_u: 'u'|'U';
_v: 'v'|'V';
_w: 'w'|'W';
_x: 'x'|'X';
_y: 'y'|'Y';
_z: 'z'|'Z';
and then explode the string literals:
switch: _s _w _i _t _c _h;
while: _w _h _i _l _e;

Getting vehicle ID

I am trying to get vehicle id as follow:
mobility = TraCIMobilityAccess().get(getParentModule());
assert(mobility);
traci = mobility->getCommandInterface();
traciVehicle = mobility->getVehicleCommandInterface();
cout<< mobility->getExternalId();
But it returns an invalid vehicle id. What is wrong?
Please help me to solve this problem. Thanks.
What do you mean by an invalid vehicle id? The way you are getting the identifier is the one used by sumo. If that is the case, can you specify what do you expect as an identifier? (that of omnet which starts from [1]?)
As the id of SUMO and that one apparent in omnet are not the same (the order of creation), you may add the following to get your own id (that matches the one of omnet) :
in the ".h" file of your TraCIDemo11p, add your id:
protected:
int your_id;//added
in the ".c" file of your TraCIDemo11p, affect the index in your id:
if (stage == 0) {
...
your_id = getParentModule()->getIndex();//added
...
next, in the place you want to verify a statement, add this:
EV << "My SUMO id = " << mobility->getExternalId() << endl;
EV << "My VEINS id = " << your_id /*or just : getParentModule()->getIndex()*/<< endl;
I hope this helps.
You can try the FindModlue::findHost() in DemoBaseApplLayer::initialize(int stage) in DemoBaseApplLayer.cc:
EV << FindModule<BaseMobility*>::findHost(getParentModule())->getId() << endl;
It will first return the host module and then use the getId() function to get its id.
For better understanding:
Firstly, you can run the simulation to see the indexing of the whole simulation and it would be like this:
Simulation information in veins
As read from the figure, each objects are assigned to a number, e.g. node[0]has the id 7, besides that, each sub-modules are also assigned with id numbers, e.g.
node[0] id = 7
appl id = 8
nic id = 9
veinsmobility id = 10
All of this ids (7,8,9,10) point to the node[0], which means you can use thoese ids to identify a specific car.
In the default DemoBaseApplLayer.cc, you can find
mac = FindModule<DemoBaseApplLayerToMac1609_4Interface*>::findSubModule(getParentModule());
and
myId = mac->getMACAddress();
in the initialization function void DemoBaseApplLayer::initialize(int stage).
Therefore, you can already use the myId as the vehicle id.
By the way, the reason that you get the 18 and 20 for vehicle id, is that the returned module might just be the host module and the sub-module, e.g. 18 is for the node[*] and the 20 is for its nic sub-module.

how to replace #VARIABLE in text file with value of Emails in xml file

How i can read this xml file
<Subs>
<Sub Report="BusinessSummarySubs" EMails="lalla#yahoo.com; haha#yahoo.com">
<Sub Report="PlayerSubs" EMails="hehe#hotmail.com">
</Subs>
and replace #VARIABLE in BusinesSummarySubs.txt with EMails value in
Here is the content(part of the content) from BusinessSumarySubs.txt
CType(extensionParams(0),ParameterValue).Name = "TO"
CType(extensionParams(0),ParameterValue).Label = ""
CType(extensionParams(0),ParameterValue).Value = "#VARIABLE"
If you look here, you'll see how to search for and to access attributes. Follow the link chain to 'the same for text' and do a mental diff, if you want to get a skeleton for a minimal XML processing script to use for your next task.
Single placeholder substitution in VBScript is easy: just use Replace:
>> attr = "lalla#yahoo.com; haha#yahoo.com"
>> content = "... .Value = ""#VARIABLE"" ..."
>> ph = "#VARIABLE"
>> WScript.Echo Replace(content, ph, attr)
>>
... .Value = "lalla#yahoo.com; haha#yahoo.com" ...
>>
Something like this i suposed
set xmlDoc=CreateObject("Microsoft.XMLDOM")
xmlDoc.async="false"
xmlDoc.load("note.xml")
for each Emails in xmlDoc.documentElement.childNodes
document.write(Emails .nodename)
document.write(": ")
document.write(Emails .text)
next

interval map in C++

I need to map some intervals (actually these are intervals of addresses) to object ids.
I tried to use boost's interval_map, the example looks very pretty, it easily enumerates all intervals like:
while(it != party.end())
{
interval<ptime>::type when = it->first;
// Who is at the party within the time interval 'when' ?
GuestSetT who = (*it++).second;
cout << when << ": " << who << endl;
}
Which outputs:
----- History of party guests -------------------------
[2008-May-20 19:30:00, 2008-May-20 20:10:00): Harry Mary
[2008-May-20 20:10:00, 2008-May-20 22:15:00): Diana Harry Mary Susan
[2008-May-20 22:15:00, 2008-May-20 23:00:00): Diana Harry Mary Peter Susan
[2008-May-20 23:00:00, 2008-May-21 00:00:00): Diana Peter Susan
[2008-May-21 00:00:00, 2008-May-21 00:30:00): Peter
but it cannot do something like this:
interval<ptime>::type when =
interval<ptime>::closed(
time_from_string("2008-05-20 22:00"),
time_from_string("2008-05-20 22:01"));
GuestSetT who = party[when];
cout << when << ": " << who << endl;
it outputs: error: no match for 'operator[]' in 'party[when]'
it looks strange, since the main function of map is in operator[]
so I cannot get information "who were at the party at a given time"
Is there a ready-to-use solution for this problem?
It's somewhat counter-intuitive, but the () operator is what you're looking for. From the docs, operator() is defined as "Return[ing] the mapped value for a key x. The operator is only available for total maps."
Source: http://www.boost.org/doc/libs/1_54_0/libs/icl/doc/html/boost_icl/function_reference/selection.html

Generating XML with cdata using Ox?

I need to generate XML using ox but didn't get much help from the documentation. I need to generate XML like this:
<Jobpostings>
<Postings>
<Posting>
<JobTitle><cdata>Programmer Analyst 3-IT</cdata></JobTitle>
<Location><cdata>Romania,Bucharest...</cdata></Location>
<CountryCode><cdata>US</cdata> </CountryCode>
<JobDescription><cdata>class technology to develop.</cdata></JobDescription>
</Posting>
</Postings>
</jobpostings>
I have the data inside the tags as strings in variables like this:
jobtitle = "Programmer Analyst 3-IT" and so on...
I am currently using Nokogiri to generate XML but I need to work on large data, and, for the performance sake I am moving to Ox.
Any ideas on how to do this?
It's pretty simple, you just initialize new elements and append them to other elements. Unfortunately there isn't an XML builder in the Ox library though... Here's an example:
require 'ox'
include Ox
source = Document.new
jobpostings = Element.new('Jobpostings')
source << jobpostings
postings = Element.new('Postings')
jobpostings << postings
posting = Element.new('Posting')
postings << posting
jobtitle = Element.new('JobTitle')
posting << jobtitle
jobtitle << CData.new('Programmer Analyst 3-IT')
location = Element.new('Location')
posting << location
location << CData.new('Romania,Bucharest...')
countrycode = Element.new('CountryCode')
posting << countrycode
countrycode << CData.new('US')
countrycode << ' '
jobdescription = Element.new('JobDescription')
posting << jobdescription
jobdescription << CData.new('class technology to develop.')
puts dump(source)
Returns:
<Jobpostings>
<Postings>
<Posting>
<JobTitle>
<![CDATA[Programmer Analyst 3-IT]]>
</JobTitle>
<Location>
<![CDATA[Romania,Bucharest...]]>
</Location>
<CountryCode>
<![CDATA[US]]> </CountryCode>
<JobDescription>
<![CDATA[class technology to develop.]]>
</JobDescription>
</Posting>
</Postings>
</Jobpostings>

Resources