Question

I am using antlr-3.4-complete.jar which i believe is using StringTemplate version 3.2.1

I have the following productions in the tree grammar

functionCall 
  : ^(FUNCCALL NCName pr+=params*) ->template(n={$NCName.text},p={$pr})"<n> <p>"

The above StringTemplate runs correctly and is generating correct output.

I have another production in the same grammar which is very similar to the production above

step  
  :  axisSpecifier nodeTest pred+=predicate* 
       ->template(a={$axisSpecifier.st},n={$nodeTest.st},pc={$pred})"<a> <n> <pc>"
  ;

But when i print the template it goes in infinite recursion, the stack is as below

Exception in thread "main" java.lang.StackOverflowError
    at org.antlr.stringtemplate.StringTemplate.getAttributeRenderer(StringTemplate.java:1080)
    at org.antlr.stringtemplate.StringTemplate.getAttributeRenderer(StringTemplate.java:1080)
    at org.antlr.stringtemplate.StringTemplate.getAttributeRenderer(StringTemplate.java:1080)
    at org.antlr.stringtemplate.StringTemplate.getAttributeRenderer(StringTemplate.java:1080)
    at org.antlr.stringtemplate.StringTemplate.getAttributeRenderer(StringTemplate.java:1080)
    at org.antlr.stringtemplate.StringTemplate.getAttributeRenderer(StringTemplate.java:1080)
    at org.antlr.stringtemplate.StringTemplate.getAttributeRenderer(StringTemplate.java:1080)
    at org.antlr.stringtemplate.StringTemplate.getAttributeRenderer(StringTemplate.java:1080)
    at org.antlr.stringtemplate.StringTemplate.getAttributeRenderer(StringTemplate.java:1080)
    at org.antlr.stringtemplate.StringTemplate.getAttributeRenderer(StringTemplate.java:1080)
    at org.antlr.stringtemplate.StringTemplate.getAttributeRenderer(StringTemplate.java:1080)
    at org.antlr.stringtemplate.StringTemplate.getAttributeRenderer(StringTemplate.java:1080)
    at org.antlr.stringtemplate.StringTemplate.getAttributeRenderer(StringTemplate.java:1080)
    at org.antlr.stringtemplate.StringTemplate.getAttributeRenderer(StringTemplate.java:1080)
    at org.antlr.stringtemplate.StringTemplate.getAttributeRenderer(StringTemplate.java:1080)

The generated code for the above production is as below

retval.st = new StringTemplate(templateLib, "<a> <n> <pc>",new STAttrMap().put("a", (axisSpecifier14!=null?axisSpecifier14.st:null)).put("n", (nodeTest15!=null?nodeTest15.st:null)).put("pc", list_pred));

The list_pred is the list containing the StringTemplates for predicate*. When i debug the code i find that just before the above line, the individual StringTemplates are fine. By being fine i mean i can read the value in the debugger as the String value. But as soon as the above line is executed, i.e. new StringTemplate is done, the toString() method starts to fail. not only for the new StringTemplate but also for the StringTemplate list_pred

I am unable to go forward with my work, as i dont think this is a problem with my grammar, as another production with same structure is working fine.

Can this error occur because of the parameter names i have chosen?

template(a={$axisSpecifier.st},n={$nodeTest.st},pc={$pred})"<a> <n> <pc>"

if i change the names from a,n,pc to something else will it help? as i see i have used the same names other places in the grammar also.

I suspect the method

StringTemplate.breakTemplateIntoChunks() might be the reason here? as this method will parse the template.

Can someone familiar with StringTemplate internals help me with this issue?

Thanks, Regards, Vimal

UPDATE: This is the output from my AST construction, this also forms the input for treeGrammar. (VARREF abc) / (STEPS (STEP child x (PRED (< (STEPS (STEP child price)) 10)))) END

The PRED is the predicate which is also an Expr

My Tree Grammars with ST is as follows.

expr  
   :  ^('<' e1=expr e2=expr) ->template(e11={$e1.st},e21={$e2.st})"\< <e11> <e21>"  
   | mainexpr -> template(mnexpr={$mainexpr.st})"<mnexpr>"  
   ;  

mainexpr  
scope  
{  
  boolean isRLP ;  
} :   
    filterExpr ('/' {$mainexpr::isRLP = true;} relativeLocationPath)?   
     -> {$mainexpr::isRLP}? template(filtr={$filterExpr.st},rlp=  {$relativeLocationPath.st})"<filtr> <rlp>"  
     -> template(filtr={$filterExpr.st})"<filtr>"  
  | relativeLocationPath -> template(rlp={$relativeLocationPath.st})"<rlp>"  
  ;  

relativeLocationPath : ^(STEPS st+=steps+) -> template(stps={$st})"<stps>";  

steps  
  :   ^(STEP step) ->template(stp={$step.st})"<stp>"    
  ;  
step   
  :  axisSpecifier nodeTest (pred+=predicate)*  
           ->template(axs={$axisSpecifier.st},ndtst={$nodeTest.st},stppred={$pred})"<axs> <ndtst> <stppred>"  
  ;  

predicate  
  : ^(PRED expr) ->template(predexp={$expr.st})"<predexp>"  
  ;  

Output of LintMode:

Exception in thread "main" java.lang.IllegalStateException: infinite recursion to <anonymous([])@76> referenced in <anonymous([])@69>; stack trace:  
<anonymous([])@76>, attributes=[predexp=<anonymous()@75>], references=[predexp, stppred]>  
<anonymous([])@69>, attributes=[ndtst=<anonymous()@68>, stppred, axs=<anonymous()@67>], references=[axs, ndtst, stppred]>  
<anonymous([])@70>, attributes=[stp=<anonymous()@69>], references=[stp, stppred]>  
<anonymous([])@71>, attributes=[stps=List[..<anonymous()@70>..]], references=[stps, stppred]>  
<anonymous([])@72>, attributes=[rlp=<anonymous()@71>], references=[rlp, stppred]>  
<anonymous([])@73>, attributes=[mnexpr=<anonymous()@72>], references=[mnexpr, stppred]>  
<anonymous([])@75>, attributes=[e21=<anonymous()@74>, e11=<anonymous()@73>],   references=[e11, stppred]>  
<anonymous([])@76> (start of recursive cycle)  
Was it helpful?

Solution

ANTLR v3.4 uses ST v4 for its cogeneration, but for backward compatibility, the generated code uses ST v3.2.1.

You have embedded a template within itself. Turn on lint mode to find the infinite cycle in the template nesting graph.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top