gpt4 book ai didi

ANTLR StringTemplate 在渲染模板时无限循环

转载 作者:行者123 更新时间:2023-12-04 05:38:27 28 4
gpt4 key购买 nike

我正在使用 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.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)

上述生产的生成代码如下
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是包含 predicate* 的 StringTemplates 的列表.
当我调试代码时,我发现就在上一行之前,各个 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)

最佳答案

ANTLR v3.4 使用 ST v4 进行热电联产,但为了向后兼容,生成的代码使用 ST v3.2.1。

您已将模板嵌入其中。开启 lint 模式,找到模板嵌套图中的无限循环。

关于ANTLR StringTemplate 在渲染模板时无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11608841/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com