我是靠谱客的博主 丰富小虾米,最近开发中收集的这篇文章主要介绍Eclipse AST结合ASTView对ASTNode进行遍历详解 从源代码生成的语法树中获取信息,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

ASTNode类及其派生类

用于描述各种AST结点的类,每个AST结点表示源程序中的一个语法结构(名字、类型、表达式、语句、声明等),所有的AST结点按照其在语法上的关系连接形成AST树。类ASTNode是各类结点的抽象基类,各个节点类是ASTNode类的派生类。

ASTNode.COMPILATION_UNIT  //代表Compilation_Unit结点类

为了便于方位AST树,AST结点含有指向其父节点的parent域和关联的子节点域。
在ASTNode类中,以属性(property)来统一处理子节点和用户自定义的结点属性。

ASTNode getParent() //获取父节点的方法
void setProperty(String propertyName,Object data) //设置指定属性的值
Object getProperty(String  propertyName) //获得指定属性的值
Map properties() //返回结点的所有属性表
  • 在每个具体的ASTNode类中,以类常量形式声明该类结点拥有的基本属性(基本的子节点)类别,并定义了存在属性值的域和访问属性的方法。
List imports()  //该结点的所有import声明 IMPORTS_PROPERTY
List types()  //该节点的所有顶层类型声明 TYPES_PROPERTY
PackageDeclaration getPackage() //该节点的package声明
void setPackage(PackageDeclaration pkgDecl) //设置该结点的package声明
  • List类型返回值可以通过add remove set等方法操作
    例如: A.types().add(B)

  • 每个AST结点含有一组位标志 含有附加信息
    void setFlags(int flags)
    int getFlags()

  • AST支持访问者模式,每个AST结点含有方法:
    void accept(ASTVisitor visitor)

一、整体结构

  1. CompilationUnit类(编译单元 根节点)
  • types()
  • getPackage()
  • imports()
  1. TypeDeclaration类(类声明/接口声明)
  • MethodDeclaration[] getMethods() /返回类声明的方法声明序列
  • FieldDeclaration[] getFields() 返回类声明的域声明序列
  • Type getSuperclassType() 返回该类声明的超类类型或null
  • void setSuperclassType(Type superclassType) 设置或清除超类
  1. MethodDeclaration类(方法声明/构造器声明)
  • Block getBody() 方法体/null
  • void setBody() 设置或清除方法体
  • SimpleName getName() 返回方法名
  • void setName(SimpleName methodName) 设置方法名
  • Type getReturnType2() 返回方法返回类型
  • void setReturnType2(Type type) 设置返回类型
  • List parameters() 方法的参数序列
  • boolean isConstrunctor() 返回是否在生命构造器
  • void setConstrunctor(boolean isConstructor) 设置是否在声明构造器

二、语句 Statement类 语句节点类的基类

  1. Block类(语句块)//花括号内语句序列
  • List statements() //返回语句块中语句序列
  1. ExpressionStatement类(表达式语句)
  • Expression getExpression() //返回语句中的表达式
  • void setExpression(Expression expression) //设置语句中的表达式
  1. IfStatement(if语句)
  • Expression getExpression() //返回if语句中的表达式
  • void setExpression(Expression expression) //设置if语句中的表达式
  • Statement getThenStatement() //返回if语句中的then分支
  • void setThenStatement(Statement statement) //设置then分支
  • Statement getElseStatement() //返回if语句中的else分支
  • void setElseStatement(Statement statement) //设置else分支
  1. WhileStatement(while语句)
  • Expression getExpression() //返回while语句中的表达式
  • void setExpression(Expression expression) //设置while语句中的表达式
  • Statement getBody() //返回while语句体
  • void setBody(Statement statement) //设置while语句体
  1. EmptyStatement(空语句)
    表示由分号组成的语句
  2. BreakStatement和ContinueStatement(break语句 continue语句)
    break label;
    continue label;
  • getLabel() //访问标号
  • setLabel() //设置标号
  1. ReturnStatement(返回语句)
  • Expression getExpression() //返回return语句中的表达式
  • void setExpression(Expression expression) //设置return语句中的表达式

三、表达式 Expression类 表达式节点的基类

  1. MethodInvocation类(方法调用)
  • SimpleName getName() //返回调用的方法名
  • void setName(SimpleName methodName) //设置方法名
  • list arguments() //返回方法调用表达式中的实参表达式序列
  1. Assignment(赋值表达式) Assignment.Operator
  • Expression getLeftHandSide() //返回赋值表达式的左部分
  • void setLeftHandSide(Expression expr)
  • Expression getRightHandSide() //返回赋值表达式的右部
  • void setRightHandSide(Expression expr)
  • Assignment.Operator getOperator() //返回赋值表达式运算符
  • void setOperator(Assignment.Operator op)
  1. InfixExpression类(中缀表达式)
  • Expression getLeftOperand() //返回左操作数
  • void setLeftOperand(Expression expr) //设置左操作数
    • Expression getRightOperand() //返回右操作数
  • void setRightOperand(Expression expr) //设置右操作数
  • InfixExpression.Operator getOperator() //返回运算符
  • void setOperator( InfixExpression.Operator op)
    InfixExpression.Operator:+ - * / % == …
  1. PrefixExpression(前缀表达式)
  • Expression getOperand() //返回operand
  • void setOperand(Expression expr) //设置operand
  • PrefixExpression.Operator getOperator() //返回运算符
  • void setOperator( PrefixExpression.Operator op)
    PrefixExpression.Operator: +PLUS -MINUS !NOT
  1. ParenthesizedExpresion(带括号的表达式)
  • Expression getExpression() //返回表达式
  • void setExpression(Expression expression) //设置表达式
  1. NumberLiteral(整数)
  • String getToken() // 返回对应的整数串
  • void setToken(String token) //设置整数串
  1. Name类

QualifiedName // a.b的受限名

  • SimpleName getName() //受限名中的名字部分 b
  • void setName(SimpleName name)
  • Name getQualifier() //受限名中的受限部分 a
  • void setQualifier(Name qualifier)

SimpleName //简单名

  • String getIdentifier() //返回标识符
  • void setIdentifier(String expression) //设置标识符
  • boolean isDeclaration() //标识符是否定义过

AST类

创建AST结点,构建AST 略

ASTVisitor类

AST的访问者抽象类,类中声明了一组访问各类AST结点的visit()方法、endVisit()、preVisit()

  • 与具体的AST结点类T相关:visit() 和endVisit()
  • 与具体的AST结点类T无关:preVisit()和postVisit()
public boolean visit(T node) //返回true 继续访问子节点;false,不访问
                               缺省:直接返回true,访问子节点
public boolean endVisit(T node) // node的子节点已经被访问或者visit后返回false之后调用

public void preVisit(ASTNode node)  //这个方法在visit(node)之前被调用

public void postVisit(ASTNode node) //这个方法在endVisit之后被调用

所有AST结点都执行在ASTNode类中定义的accept方法:

public final void accept(ASTVisitor visitor){
	if(visitor == null){
		throw new IlleagalArgumentException();
	}
	visitor.preVisit(this);//执行与结点类型无关的preVisit方法
	accept0(visitor);//调用accept0,执行与节点类型相关的visit/endVisit
	visitor.postVisit(this)//执行与节点类型无关的postVisit方法

}

使用Visitor遍历语法树

DemoVisitor.java

public class DemoVisitor extends ASTVisitor{
	@Override
	public boolean visit(PackageDeclaration node) {
		System.out.println("Package:"+node.getName());
		return true;
	}
	@Override
	public boolean visit(ImportDeclaration node) {
		System.out.println("Import:"+node.toString());
		return true;
	}
	public boolean visit(VariableDeclaration node) {
		System.out.println("Package:"+node.toString());
		return true;
	}
	@Override
	public boolean visit(FieldDeclaration node) {
		for(Object obj:node.fragments()) {
			VariableDeclarationFragment v = (VariableDeclarationFragment)obj;
			System.out.println("Field:t" + v.getName());
		}
		return true;
	}

	@Override
	public boolean visit(MethodDeclaration node) {
		System.out.println("Method:t" + node.getName());
		return true;
	}
 
	@Override
	public boolean visit(TypeDeclaration node) {
		System.out.println("Class:t" + node.getName());
		return true;
	}

}
//生成语法树
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setSource(content.toCharArray());		parser.setKind(ASTParser.K_COMPILATION_UNIT);//解析的代码类型:一个编译单元
CompilationUnit cu = (CompilationUnit)parser.createAST(null);
//Visitor遍历
DemoVisitor visitor = new DemoVisitor();
cu.accept(visitor);

最后

以上就是丰富小虾米为你收集整理的Eclipse AST结合ASTView对ASTNode进行遍历详解 从源代码生成的语法树中获取信息的全部内容,希望文章能够帮你解决Eclipse AST结合ASTView对ASTNode进行遍历详解 从源代码生成的语法树中获取信息所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部