Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在java中使用AST的访问者_Java_Abstract Syntax Tree - Fatal编程技术网

如何在java中使用AST的访问者

如何在java中使用AST的访问者,java,abstract-syntax-tree,Java,Abstract Syntax Tree,我使用生成一些给定Java源代码的AST。 生成AST后,我拥有根节点 如何使用ASTVisitor,以便解析AST以获取所有叶节点 一个例子是: package de.vogella.jdt.astsimple.handler; import java.util.ArrayList; import java.util.List; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.Metho

我使用生成一些给定Java源代码的AST。 生成AST后,我拥有根节点

如何使用
ASTVisitor
,以便解析AST以获取所有叶节点

一个例子是:

package de.vogella.jdt.astsimple.handler;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.MethodDeclaration;

public class MethodVisitor extends ASTVisitor {
  List<MethodDeclaration> methods = new ArrayList<MethodDeclaration>();
    @Override
    public boolean visit(MethodDeclaration node) {
      methods.add(node);
      return super.visit(node);
    }

    public List<MethodDeclaration> getMethods() {
      return methods;
    }
}
package de.vogella.jdt.astsimple.handler;
导入java.util.ArrayList;
导入java.util.List;
导入org.eclipse.jdt.core.dom.ASTVisitor;
导入org.eclipse.jdt.core.dom.MethodDeclaration;
公共类MethodVisitor扩展了一个类Visitor{
列表方法=新的ArrayList();
@凌驾
公共布尔访问(MethodDeclaration节点){
方法:添加(节点);
返回超级访问(节点);
}
公共列表getMethods(){
返回方法;
}
}
访客模式 如果您还不熟悉特定的设计模式,我建议您先阅读一下

本质上,它归结为使用双重分派在
Visitor
类上调用适当的方法,将访问的对象作为参数传递。一般情况下,其实现方式与以下类似(YMMV):


通过调用此方法并传递所检查的每个节点,您可以确定该节点是否没有子节点(返回数组的
长度将为0),并将这些子节点添加到
ASTVisitor
中的
集合中以跟踪它们。

这可能不是正确的方法,但这可以获得所有叶节点

1) 维护两组节点,例如
S1
S2

2) 遍历所有节点并将每个节点添加到
S1

3) 如果
node.getParent()!=null,然后将
节点.getParent()添加到
S2

4) 这意味着
S1
跟踪所有节点,而
S2
跟踪所有内部节点。因此叶节点是
S1-S2

希望能有所帮助。

这个怎么样:
public interface Node {
    void acceptVisitor(Visitor v);

    Collection<Node> getChildren();
}

// Incomplete implementation, for demonstration only
public class SubNode implements Node {

    @Override
    public void acceptVisitor(Visitor v) {
        if(v.preVisit(this)) {
            v.visit(this);
            v.postVisit(this);
        }
        getChildren().forEach(child -> child.accept(v));
    }
}

public interface Visitor {
    boolean preVisit(Node node);

    void visit(Node node);

    void visit(SubNode node);

    void postVisit(Node node);
}
public Object[] getChildren(ASTNode node) {
    List list= node.structuralPropertiesForType();
    for (int i= 0; i < list.size(); i++) {
        StructuralPropertyDescriptor curr= (StructuralPropertyDescriptor) list.get(i);
            Object child= node.getStructuralProperty(curr);
        if (child instanceof List) {
                return ((List) child).toArray();
        } else if (child instanceof ASTNode) {
            return new Object[] { child };
            }
        return new Object[0];
    }
}