扩展 ANTLR3 AST

发布于 2024-12-08 07:42:52 字数 621 浏览 1 评论 0原文

使用 ANTLR2,您可以在语法定义文件中定义类似的内容:

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

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

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

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

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

编辑

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

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

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

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

With ANTLR2, you could define something like this in grammar definition file:

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

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

And then, you could create a class:

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

Any ideea if something like this can be used (delegate class creation to AST factory instead of me doing the tree replication manually)? It's not working just by simple grammar definition copy from old to new format, and I tried to search their site and samples for somthing similar. Any hints?

EDIT

I'm not trying to create custom tokens, but custom 'node parsers'.

In order to 'execute' a tree you have 2 choices (as far as I understood):

  1. create a 'tree visitor' and handle values, or
  2. create a tree parser by 'almost-duplicating' the grammar definition.

In v2 case, I could decorate the tree node to whateveer method I would have liked and then call them after the parser ran by just calling something like 'execute' from root node.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

零崎曲识 2024-12-15 07:42:52

我对C#了解很少,但与Java目标应该没有太大区别。

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

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

然后,您创建一个扩展 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

I know little C#, but there shouldn't be much difference with the Java target.

You can create - and let ANTLR use - a custom tree by setting the ASTLabelType in the options { ... } section (an XTree in this case):

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

You then create a custom class which extends a 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());
  }
}

and when you create an instance of your TParser, you must create and set a custom TreeAdaptor which creates instances of your 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();
  }
}

Running the demo:

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

will print:

XTree.text=ROOT, children=3

For more info, see: http://www.antlr.org/wiki/display/ANTLR3/Tree+construction

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文