antlr / stringtemplate4

StringTemplate 4
http://www.stringtemplate.org
Other
955 stars 231 forks source link

StackOverflowException overriding Antlr's AbstractParseTreeVisitor Methods #221

Closed thron7 closed 5 years ago

thron7 commented 5 years ago

I'm not sure if this is an ST or Antlr issue. But since the SOE appears in the ST code, I'm posting it here.

I'm working on Antlr parse tree visitors that return ST templates. In my own class deriving from AbstractParseTreeVisitor I'm overriding defaultResult and aggregateResult, to collect all sub-results from multiple node children. I just want to collect them so they are not lost while going in and out of visiting the tree. Here is my code:

    @Override
    protected ST defaultResult() {
        ST st = new ST("<[myAttribute]>");
        st.add("myAttribute", "");  // without an add() op here a StackOverflowException appears
        return st;
    }

    @Override
    protected ST aggregateResult(ST aggregate, ST nextResult) {
        Optional.ofNullable(nextResult)
                .ifPresent(nr -> aggregate.add("myAttribute", nr));
        return aggregate;
    }

Without the call to st.add() in defaultResult() I get a SOE like this:

Exception in thread "main" java.lang.StackOverflowError
    at org.stringtemplate.v4.InstanceScope.<init>(InstanceScope.java:63)
    at org.stringtemplate.v4.Interpreter.pushScope(Interpreter.java:1216)
    at org.stringtemplate.v4.Interpreter.exec(Interpreter.java:140)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:691)
    at org.stringtemplate.v4.Interpreter.writeIterator(Interpreter.java:721)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:696)
    at org.stringtemplate.v4.Interpreter.writeObjectNoOptions(Interpreter.java:623)
    at org.stringtemplate.v4.Interpreter._exec(Interpreter.java:283)
    at org.stringtemplate.v4.Interpreter.exec(Interpreter.java:143)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:691)
    at org.stringtemplate.v4.Interpreter.writeIterator(Interpreter.java:721)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:696)
    at org.stringtemplate.v4.Interpreter.writeObjectNoOptions(Interpreter.java:623)
    at org.stringtemplate.v4.Interpreter._exec(Interpreter.java:283)
    at org.stringtemplate.v4.Interpreter.exec(Interpreter.java:143)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:691)
    at org.stringtemplate.v4.Interpreter.writeIterator(Interpreter.java:721)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:696)
    at org.stringtemplate.v4.Interpreter.writeObjectNoOptions(Interpreter.java:623)
    at org.stringtemplate.v4.Interpreter._exec(Interpreter.java:283)
    at org.stringtemplate.v4.Interpreter.exec(Interpreter.java:143)
        ...

or this

Exception in thread "main" java.lang.StackOverflowError
    at java.util.Collections$SynchronizedMap.get(Collections.java:2584)
    at org.stringtemplate.v4.Interpreter.getAttribute(Interpreter.java:1135)
    at org.stringtemplate.v4.Interpreter._exec(Interpreter.java:187)
    at org.stringtemplate.v4.Interpreter.exec(Interpreter.java:143)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:691)
    at org.stringtemplate.v4.Interpreter.writeIterator(Interpreter.java:721)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:696)
    at org.stringtemplate.v4.Interpreter.writeObjectNoOptions(Interpreter.java:623)
    at org.stringtemplate.v4.Interpreter._exec(Interpreter.java:283)
    at org.stringtemplate.v4.Interpreter.exec(Interpreter.java:143)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:691)
    at org.stringtemplate.v4.Interpreter.writeIterator(Interpreter.java:721)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:696)
    at org.stringtemplate.v4.Interpreter.writeObjectNoOptions(Interpreter.java:623)
    at org.stringtemplate.v4.Interpreter._exec(Interpreter.java:283)
    at org.stringtemplate.v4.Interpreter.exec(Interpreter.java:143)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:691)
    at org.stringtemplate.v4.Interpreter.writeIterator(Interpreter.java:721)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:696)
    at org.stringtemplate.v4.Interpreter.writeObjectNoOptions(Interpreter.java:623)
    at org.stringtemplate.v4.Interpreter._exec(Interpreter.java:283)
    at org.stringtemplate.v4.Interpreter.exec(Interpreter.java:143)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:691)
    at org.stringtemplate.v4.Interpreter.writeIterator(Interpreter.java:721)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:696)
    at org.stringtemplate.v4.Interpreter.writeObjectNoOptions(Interpreter.java:623)
    at org.stringtemplate.v4.Interpreter._exec(Interpreter.java:283)
    at org.stringtemplate.v4.Interpreter.exec(Interpreter.java:143)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:691)
    at org.stringtemplate.v4.Interpreter.writeIterator(Interpreter.java:721)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:696)
    at org.stringtemplate.v4.Interpreter.writeObjectNoOptions(Interpreter.java:623)
    at org.stringtemplate.v4.Interpreter._exec(Interpreter.java:283)
    at org.stringtemplate.v4.Interpreter.exec(Interpreter.java:143)
    at org.stringtemplate.v4.Interpreter.writeObject(Interpreter.java:691)
        ...

Am I doing something wrong here? Or is it in fact a bug? It feels like I would be inserting a template into itself, but I can't see where this should happen. And why would the st.add() call fix it?!

This is Antlr 4.7.2 and StringTemplate 4.0.2.

parrt commented 5 years ago

Hmm...this is usually an issue of cycles in a data structure that ST is trying to display. There is a debug mode I believe that tracks this stuff, at least in Java version.

thron7 commented 5 years ago

Ok, I havn't found much about debugging for ST 4 (most pertains to ST 3). The docs suggest the Inspector GUI but using that before my render() call runs into the same SOE. There is a debug option in the Interpreter class, but I never instantiated that directly. How would I deploy a custom Interpreter instance? Or is there a better way?

parrt commented 5 years ago

can't remember. i seem to recall a global static you can set or whatever that tells it to track and look for inf recursion. sorry I can't be more specific.

thron7 commented 5 years ago

No worries. I don't seem to be able to find it, but I have a work-around so I'm not stuck. You might close this, I just wanted to let somebody know. I read something about dynamic scoping in StringTemplate so maybe there is some variable capture going on, but I know too little about ST to follow up. - Thanks anyway.