使用flex和bison组合或从java字节码生成解析树

使用flex和bison组合或从java字节码生成解析树,java,bison,bytecode,abstract-syntax-tree,flex-lexer,Java,Bison,Bytecode,Abstract Syntax Tree,Flex Lexer,我打算从java字节码生成解析树。典型的字节码如下所示: public class org.scandroid.testing.InvokeCallArgTest extends org.scandroid.testing.SourceSink{ public org.scandroid.testing.InvokeCallArgTest(); Code: 0: aload_0 1: invokespecial #8; //Method org/scandroid/t

我打算从java字节码生成解析树。典型的字节码如下所示:

public class org.scandroid.testing.InvokeCallArgTest extends org.scandroid.testing.SourceSink{
public org.scandroid.testing.InvokeCallArgTest();
  Code:
   0:   aload_0
   1:   invokespecial   #8; //Method org/scandroid/testing/SourceSink."<init>":()V
   4:   return

public static java.lang.String invokeCallArgSourceSpec();
  Code:
   0:   iconst_1
   1:   newarray char
   3:   astore_0
   4:   aload_0
   5:   invokestatic    #16; //Method org/scandroid/testing/SourceSink.load:([C)V
   8:   new     #20; //class java/lang/String
   11:  dup
   12:  aload_0
   13:  invokespecial   #22; //Method java/lang/String."<init>":([C)V
   16:  areturn

public static int invokeCallArgSourceSpecInt();
  Code:
   0:   iconst_1
   1:   newarray char
   3:   astore_0
   4:   aload_0
   5:   invokestatic    #16; //Method org/scandroid/testing/SourceSink.load:([C)V
   8:   aload_0
   9:   arraylength
   10:  ireturn

public static void invokeCallArgSinkSpecInt(int);
  Code:
   0:   iload_0
   1:   invokestatic    #30; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   4:   invokestatic    #36; //Method org/scandroid/testing/SourceSink.sink:(Ljava/lang/Object;)V
   7:   return

public static void invokeCallArgSinkSpecBiInt(int, int);
  Code:
   0:   iload_0
   1:   iload_1
   2:   iadd
   3:   invokestatic    #30; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   6:   invokestatic    #36; //Method org/scandroid/testing/SourceSink.sink:(Ljava/lang/Object;)V
   9:   return

}
公共类org.scandroid.testing.InvokeCallArgTest扩展org.scandroid.testing.SourceSink{
public org.scandroid.testing.InvokeCallArgTest();
代码:
0:aload_0
1:invokespecial#8;//方法org/scandroid/testing/SourceSink。“”:()V
4:返回
public static java.lang.String invokeCallArgSourceSpec();
代码:
0:iconst_1
1:newarray字符
3:astore_0
4:aload_0
5:invokestatic#16;//方法org/scandroid/testing/SourceSink.load:([C)V)
8:new#20;//类java/lang/String
11:dup
12:aload_0
13:invokespecial#22;//方法java/lang/String。“”:([C)V
16:轮到你了
公共静态int invokeCallArgSourceSpecInt();
代码:
0:iconst_1
1:newarray字符
3:astore_0
4:aload_0
5:invokestatic#16;//方法org/scandroid/testing/SourceSink.load:([C)V)
8:aload_0
9:排列长度
10:我轮到你了
公共静态void invokeCallargSinkspectint(int);
代码:
0:iload_0
1:invokestatic#30;//方法java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
4:invokestatic#36;//方法org/scandroid/testing/SourceSink.sink:(Ljava/lang/Object;)V
7:返回
公共静态void invokeCallArgSinkSpecBiInt(int,int);
代码:
0:iload_0
1:iload_1
2:iadd
3:invokestatic#30;//方法java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
6:invokestatic#36;//方法org/scandroid/testing/SourceSink.sink:(Ljava/lang/Object;)V
9:返回
}

我的目标是生成解析树或抽象语法树。我计划使用flex和bison combo。我只想知道这是一种正确的方法吗?我应该从头开始,还是有其他工具可以处理从字节码创建AST的问题?

当然,第一步是弄清楚您真正想要的是什么与标准语言相比,字节码的用途要小得多,因为它缺少变量、作用域、未标记的中断和其他最方便用AST表示的功能。您仍然可以有一个树,其中包含表示类、方法、指令和操作数的节点,但在每个方法中,代码基本上都是flat


至于实际实现,由于上述原因,我不知道有谁用字节码创建了AST进行操作。最接近的是字节码汇编程序的解析器。例如,你可以找到我的汇编程序的语法。它使用Ply,这是基于Python的Lex和Yacc实现,所以应该类似。Bu这是一个解析树,旨在帮助组装类文件的过程,而不是用于任何特定的编程转换。

Java字节码不是真正要解析的文本;没有文档化的“语法”。为什么您认为这很有用?您好,我的目标是比较两个不同版本的程序字节码生成的两个AST。我希望得到语义差异,而不是由diff工具返回的逐行差异。使用eclipse jdt插件,您可以从类文件/java文件生成AST。不确定是否支持字节码解析ed.你不需要解析器,只需要一个扫描器。这是一种常规语言,不是上下文无关的语言。嗨,我的目标是比较两个不同版本的程序字节码生成的两个AST。我想要的是语义差异,而不是diff工具返回的逐行差异。字节码“AST”基本上,这会给您带来行差异。在反编译器的情况下,它最多有助于方法的重新排序。在反编译器的情况下,它们如何检索变量和范围?还有一些功能,如异常处理,请尝试catch block?因为它在字节码中不可见/在大多数反编译器的情况下,依赖Java com留下的模式听起来你真正想要的是一个反编译程序。反编译程序是我能得到的最后一件东西。但有时它可能会因为混淆而失败。