【问题标题】:Extend ANTLR3 AST's扩展 ANTLR3 AST
【发布时间】:2011-10-03 13:34:49
【问题描述】:

使用 ANTLR2,您可以在语法定义文件中定义如下内容:

options
{
   language = "CSharp";
   namespace = "Extended.Tokens";
}

tokens {
   TOKEN<AST=Extended.Tokens.TokenNode>;
}

然后,您可以创建一个类:

public class TokenNode: antlr.BaseAST
{
    ...
}

是否可以使用类似的东西(将类创建委托给 AST 工厂,而不是我手动进行树复制)?仅通过从旧格式到新格式的简单语法定义复制不起作用,我尝试在他们的网站和示例中搜索类似的东西。有什么提示吗?

编辑

我不是在尝试创建自定义令牌,而是自定义“节点解析器”。

为了“执行”一棵树,你有两个选择(据我所知):

  1. 创建一个“树访问者”并处理值,或者
  2. 通过“几乎复制”语法定义来创建树解析器。

在 v2 的情况下,我可以将树节点装饰成我喜欢的任何方法,然后在解析器运行后通过从根节点调用类似“执行”的方法来调用它们。

【问题讨论】:

  • 抱歉,打错了:这个定义是在 v2.2 中定义的。我编辑了帖子。
  • 这有意义吗?有没有办法在 ANTLR3 中实现类似于 ANTLR2 的东西?
  • 不是自定义令牌,而是自定义“节点解析器”。为了“执行”一棵树,您有两个选择(据我所知):1.创建一个“树访问者”并处理值和 2.通过“几乎复制”语法定义来创建树解析器。在 v2 的情况下,我可以将树节点装饰成我喜欢的任何方法,然后在解析器运行后通过从根节点调用类似“执行”的方法来调用它们。

标签: tree antlr antlr3 tree-nodes heterogeneous


【解决方案1】:

我对 C# 知之甚少,但与 Java 目标应该没有太大区别。

您可以通过在options { ... } 部分中设置ASTLabelType(在本例中为XTree)来创建并让ANTLR 使用自定义树:

T.g

grammar T;

options {
  output=AST;
  ASTLabelType=XTree;
}

tokens {
  ROOT;
}

@parser::header {
  package demo;
  import demo.*;
}

@lexer::header {
  package demo;
  import demo.*;
}

parse
  :  Any* EOF -> ^(ROOT Any*)
  ;

Any
  :  .
  ;

然后您创建一个扩展 CommonTree 的自定义类:

demo/XTree.java

package demo;

import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;

public class XTree extends CommonTree {

  public XTree(Token t) {
    super(t);
  }

  public void x() {
    System.out.println("XTree.text=" + super.getText() + ", children=" + super.getChildCount());
  }
}

当您创建TParser 的实例时,您必须创建并设置一个自定义TreeAdaptor,它会创建您的XTree 的实例:

demo/Main.java

package demo;

import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;

public class Main {

  public static void main(String[] args) throws Exception {
    String source = "ABC";
    TLexer lexer = new TLexer(new ANTLRStringStream(source));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    parser.setTreeAdaptor(new CommonTreeAdaptor(){
      @Override
      public Object create(Token t) {
        return new XTree(t);
      }
    }); 
    XTree root = (XTree)parser.parse().getTree();
    root.x();
  }
}

运行演示:

java -cp antlr-3.2.jar org.antlr.Tool T.g -o demo/
javac -cp antlr-3.2.jar demo/*.java
java -cp .:antlr-3.2.jar demo.Main

将打印:

XTree.text=ROOT, children=3

欲了解更多信息,请参阅:http://www.antlr.org/wiki/display/ANTLR3/Tree+construction

【讨论】:

  • 这不是我一直在寻找的......在我看到的示例中(antlr2.org/doc/trees.html - “AST 工厂”和“异构 ASTs”),您可以定义要为特定令牌。在您的示例中,您可以在解析树后创建单个对象类型 (XTree)。
  • 好吧,在CommonTreeAdaptorcreate 方法中,您可以根据作为参数传递的令牌返回您喜欢的任何树,无论是XTree 还是YTree ,没关系。在这种情况下,您可能希望将 ASTLabelType 更改为 CommonTree 或您的所有自定义树扩展的其他类。
  • 我想我找到了我要找的东西:antlr.org/wiki/display/ANTLR3/Tree+construction(异构树节点)。感谢提示! :-)
  • 刚刚发布了一个链接! :) 当然,不客气。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-24
  • 2020-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-25
相关资源
最近更新 更多