[stringtemplate-interest] Problem with null actual parameters (in anonymous templates)
Iztok Kavkler
iztok.kavkler at fmf.uni-lj.si
Fri Mar 20 13:14:21 PDT 2009
I'm sorry, there was a slight mistake in the example, the '?' was
missing (so the pl could not be empty).
expr: id=IDENTIFIER '(' (pl+=expr (',' pl+=expr)*)? ')'
-> template(id={$id.text}, par={$pl})
<< <id>(<par; separator=", ">) >> ;
The reason for the infinite recursion is as follows: when processing
f1(f2(), f3())
the first instance of the template gets paramaters
1) id = "f1", par = [f2(), f3()]
because expr rule is recursive, template is invoked recursively for both
parameters, first with
2) id = "f2", par = null
at this point, the engine will think that "par" is a missing parameter
and will check the enclosing instance, which is 1), obtaining
par = [f2(), f3()]
and so on to infinity.
> Wow. Yes, I had not thought of this. sometimes you want to say "empty"
> not missing. I'm not sure I see the infinite loop though. the only way
> to get an infinite loop is if they template is ultimately and enclosing
> template of itself.
>
> Ter
> On Mar 18, 2009, at 9:10 AM, Iztok Kavkler wrote:
>
>> If an actual parameter to a template without formal attributes is
>> specified but its value is null, the attribute will be looked-up in
>> enclosing instances. This will almost always break recursive invocations
>> of templates (they are common in grammars with output=template), because
>> it creates cycles in the list of enclosing instances.
>>
>> For example, the following snippet should parse and print back nested
>> functions with any number of parameters, like " f1(f2(), f3()) ", but it
>> actually dies with stack owerflow (or it diagnoses the cycle when lint
>> is on):
>>
>> expr: id=IDENTIFIER '(' (pl+=expr (',' pl+=expr)*) ')'
>> -> template(id={$id.text}, par={$pl})
>> << <id>(<par; separator=", ">) >> ;
>>
>> The solution is simple: when checking for attributes th function
>> StringTemplate.get should return null if the attribute is present but
>> its value is null (some modifications to setAttribute are also
>> necessary). The following patch to StringTemplate.java does the trick:
>>
>> 486c486
>> < if ( value==null || name==null ) {
>> ---
>>> if ( name==null ) {
>> 510a511,516
>>>
>>> // null value should be added only if the attribute does not
>>> yet exist
>>> if ( value==null ) {
>>> return;
>>> }
>>>
>> 772a779,783
>>> // there is an actual argument, but it is null
>>> if ( o==null && self.attributes!=null &&
>> self.attributes.containsKey(attribute) ) {
>>> return o;
>>> }
>>>
>> _______________________________________________
>> 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