在Java中,如何从类文件中获取抽象语法树?

时间:2012-06-19 11:14:49

标签: java eclipse-plugin abstract-syntax-tree eclipse-jdt jikes

我们知道,我们可以使用像

这样的工具从源代码中获取抽象语法树
org.eclipse.jdt.astview

但是考虑到已编译的类文件,如何获取AST?有现成的工具吗?可以 soot 吗?

谢谢!

3 个答案:

答案 0 :(得分:4)

  

但是考虑到已编译的类文件,如何获取AST?

你做不到。从技术上讲,从“.class”文件重建原始源代码的AST是不可能的。所需的许多信息不再以任何形式出现,其他信息也不可逆转地转变。

  

是否有现有工具?

没有

标准的“答案”是使用反编译器,但是:

  • 反编译器无法重建原始AST(见上文)
  • 反编译器的输出通常甚至不会与原始源代码
  • 类似
  • 通常反编译的代码甚至都不会编译。

答案 1 :(得分:0)

反编译并做同样的事情。

字节码没有S,字节码是AST到字节码转换的结果

答案 2 :(得分:0)

对于给定的类文件,我们首先使用 jad 等工具对其进行反编译,然后我们就可以得到“源代码”。

即使来自反编译的这个“源代码”与原始代码不完全相同,它也会共享相同的语义。以下是一个简单的测试。

原始java文件:

package shape.circle;
public class Circle
{   int r;  // this is radius of a circle
    public Circle(int r)
    {   this.r = r;
    }

    /* get the diameter
       of this circle
    */
    public int getDiameter()
    {
        if(r==0)
        {   System.out.println("r is 0");
            return -1;
        }
        else
        {   int d = multiply(2,r);
            return d;
        }
    }

    int multiply(int a, int b)
    {   int c;
        c = a * b;
        return c;
    }
}

以下是来自 Circle.class 的反编译java文件。

package shape.circle;
import java.io.PrintStream;
public class Circle
{

    public Circle(int i)
    {  r = i;
    }

    public int getDiameter()
    {   if(r == 0)
        {   System.out.println("r is 0");
            return -1;
        } else
        {
            int i = multiply(2, r);
            return i;
        }
    }

    int multiply(int i, int j)
    {
        int k = i * j;
        return k;
    }

    int r;
}

它们几乎相同。然后和以前一样,我们可以使用该工具获取源代码

org.eclipse.jdt.astview

获得AST。