ANTLR StringTemplate бесконечный цикл при рендеринге шаблона
Я использую antlr-3.4-complete.jar, который я считаю, использует StringTemplate версии 3.2.1
У меня есть следующие произведения в грамматике дерева
functionCall
: ^(FUNCCALL NCName pr+=params*) ->template(n={$NCName.text},p={$pr})"<n> <p>"
Вышеуказанный StringTemplate работает правильно и генерирует правильный вывод.
У меня есть другая продукция в той же грамматике, которая очень похожа на вышеприведенную.
step
: axisSpecifier nodeTest pred+=predicate*
->template(a={$axisSpecifier.st},n={$nodeTest.st},pc={$pred})"<a> <n> <pc>"
;
Но когда я печатаю шаблон, он идет в бесконечной рекурсии, стек, как показано ниже
Exception in thread "main" java.lang.StackruError
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)
Сгенерированный код для вышеупомянутой продукции, как показано ниже
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));
list_pred
список, содержащий шаблоны String для predicate*
, Когда я отлаживаю код, я нахожу, что непосредственно перед строкой выше, отдельные StringTemplates в порядке. Будучи в порядке, я имею в виду, что могу прочитать значение в отладчике как строковое значение. Но как только вышеприведенная строка выполнена, т.е. new StringTemplate
сделано, то toString()
метод начинает терпеть неудачу. не только для нового StringTemplate, но и для StringTemplate list_pred
Я не могу продолжать свою работу, так как не думаю, что это проблема с моей грамматикой, так как другой продукт с такой же структурой работает нормально.
Может ли эта ошибка произойти из-за имен параметров, которые я выбрал?
template(a={$axisSpecifier.st},n={$nodeTest.st},pc={$pred})"<a> <n> <pc>"
если я поменяю имена с a
,n
,pc
чему-то другому это поможет? как я вижу, я использовал те же имена и в других местах грамматики.
Я подозреваю метод
StringTemplate.breakTemplateIntoChunks()
может быть причина здесь? так как этот метод будет разбирать шаблон.
Может ли кто-нибудь, знакомый с внутренними компонентами StringTemplate, помочь мне с этой проблемой?
Спасибо, С уважением, Вимал
ОБНОВЛЕНИЕ: Это вывод из моей конструкции AST, это также формирует вход для treeGrammar. (VARREF abc) / (STEPS (STEP child x (PRED (< (STEPS (STEP child price)) 10)))) END
PRED
это предикат, который также является Expr
Мое древо грамматики с ST выглядит следующим образом.
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>"
;
Вывод 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)
1 ответ
ANTLR v3.4 использует ST v4 для когенерации, но для обратной совместимости сгенерированный код использует ST v3.2.1.
Вы встроили шаблон в себя. Включите режим lint, чтобы найти бесконечный цикл в графе вложенности шаблона.