【问题标题】:using flex and bison combo or generating parse tree from java bytecode使用 flex 和 bison 组合或从 java 字节码生成解析树
【发布时间】:2023-04-09 03:14:01
【问题描述】:

我打算从 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

}

我的目标是生成解析树或抽象语法树。我打算使用 flex 和 bison 组合。只是想知道这将是一个正确的方法吗?我应该从头开始还是有其他工具可用于处理从字节码创建 AST?

【问题讨论】:

  • Java 字节码并不是真正要解析的文本;没有记录在案的“语法”。为什么你认为这很有用?
  • 您好,我的目标是比较从两个不同版本的程序字节码生成的两个 AST。我想要语义差异,而不是 diff 工具返回的逐行差异
  • 使用 eclipse-jdt 插件可以从类文件/java 文件生成 AST。不确定是否支持字节码解析。
  • 你不需要解析器,只需要一个扫描器。它是一种常规语言,而不是上下文无关语言。

标签: java bison bytecode abstract-syntax-tree flex-lexer


【解决方案1】:

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

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

【讨论】:

  • 您好,我的目标是比较从两个不同版本的程序字节码生成的两个 AST。我想要语义差异,而不是 diff 工具返回的逐行差异。
  • 好吧,字节码“ast”基本上会给您带来线路差异。充其量它会帮助重新排序方法。
  • 嗨,如果是反编译器,他们如何检索变量和范围呢?还有诸如异常处理、try catch 块之类的功能?因为从字节码中看不到/
  • 在大多数反编译器的情况下,依赖于 Java 编译器留下的模式。听起来你真正想要的是一个反编译器。
  • 反编译器是我能得到的最后一件事。但有时它可能会因为混淆而失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-09
  • 1970-01-01
  • 2012-04-26
  • 1970-01-01
相关资源
最近更新 更多