3

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

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

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

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

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

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

编辑

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

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

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

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

4

1 回答 1

4

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

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

Tg

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
  :  .
  ;

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

演示/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

演示/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

于 2011-10-03T18:42:42.433 回答