首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >呈现模板时的ANTLR StringTemplate无限循环

呈现模板时的ANTLR StringTemplate无限循环
EN

Stack Overflow用户
提问于 2012-07-23 08:25:01
回答 1查看 768关注 0票数 2

我使用的是antlr-3.4-完全.3.4,我相信它使用的是StringTemplate版本3.2.1。

我在树语法中有以下结果

代码语言:javascript
复制
functionCall 
  : ^(FUNCCALL NCName pr+=params*) ->template(n={$NCName.text},p={$pr})"<n> <p>"

上面的StringTemplate运行正常,并正在生成正确的输出。

我在同一语法中有另一个产品,非常类似于上面的产品。

代码语言:javascript
复制
step  
  :  axisSpecifier nodeTest pred+=predicate* 
       ->template(a={$axisSpecifier.st},n={$nodeTest.st},pc={$pred})"<a> <n> <pc>"
  ;

但是当我打印模板时,它是无限递归的,堆栈如下所示

代码语言:javascript
复制
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)

以上产品的生成代码如下所示

代码语言:javascript
复制
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是包含StringTemplates for predicate*的列表。当我调试代码时,我发现就在上面的行之前,每个StringTemplates都很好。我的意思是,我可以将调试器中的值作为字符串值来读取。但是,一旦执行了上面的行(即new StringTemplate ),toString()方法就会开始失败。不仅适用于新的StringTemplate,而且也适用于StringTemplate list_pred

我无法继续我的工作,因为我不认为这是我的语法问题,因为另一个生产相同的结构是好的。

这个错误会因为我选择的参数名而发生吗?

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

如果我将名称从anpc更改为其他名称,会有帮助吗?据我所见,我在语法中也用过同样的名字。

我怀疑这种方法

StringTemplate.breakTemplateIntoChunks()可能就是这里的原因吗?因为此方法将解析模板。

熟悉StringTemplate内部结构的人能帮我解决这个问题吗?

谢谢,你好,维马尔

更新:--这是我的AST结构的输出,这也构成了treeGrammar的输入。(VARREF abc) / (STEPS (STEP child x (PRED (< (STEPS (STEP child price)) 10)))) END

PRED是谓词,也是Expr

我的树语法与ST如下所示。

代码语言:javascript
复制
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的输出:

代码语言:javascript
复制
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)  
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-23 16:22:28

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

您已经在其内部嵌入了一个模板。打开lint模式,在模板嵌套图中找到无限循环。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11608841

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档