关于Java:从抽象语法树获取控制流程图

关于Java:从抽象语法树获取控制流程图

Get Control flow graph from Abstract Syntax Tree

我有一个从ANTLR Parser Generator for Java派生的AST。 我想做的是以某种方式构造源代码的控制流程图,其中每个语句或表达式都是唯一的Node。 我知道此标识必须具有递归性,我想知道您建议的最佳选择是什么,以及ANTLR是否具有可以用于此工作的工具集。
干杯,
克里斯

编辑-我主要关心的是从AST获得控制流程图(CFG)。 这样我就可以得到源代码的树形表示。 为了明确起见,源代码和实现语言都是Java。


通常,CFG是在较低级别的表示形式(例如JVM字节码)上计算的。几年前有人对这种事情做了论文。那里可能描述了一种有用的方法来获取该表示形式。

由于您的源语言和目标语言是相同的,因此没有代码生成步骤-您已经完成了!但是,现在您可以开始使用AST了。在AST的每个节点上,您都必须问自己:这是否是"跳跃"指令?方法调用和if语句是跳转指令的示例。循环构造(如forwhile)也是如此。诸如加法和乘法之类的指令是不可跳跃的。

首先,将每个Java语句与CFG中的一个节点以及一个入口和出口节点相关联。作为第一近似,走树并:

  • 如果当前语句是一个方法调用,请找出该方法调用的相应主体的入口节点在哪里,并从当前语句指向该入口节点的边。如果该语句是方法返回,请枚举可能已调用它的位置,并在这些位置添加一条边。
  • 对于每个非跳转语句,在它与下一个语句之间取一个边。
  • 这将为您提供某种CFG。在第2步中,该过程有些繁琐,因为所调用的方法可以在库中声明,而不是在AST的其他地方声明-如果是这样,则不要在表示该条目的特殊节点上占优势或占优势库方法。

    这有意义吗?


    产生一个完全考虑所有语言的完整控制流程图
    问题比看起来难。您不仅需要识别什么
    似乎是"基本块",但是您必须确定函数调用
    (这很容易,但是确定目标可能会比较困难),
    诸如类初始化程序之类的幕后操作可能发生的地方。
    并担心可能发生异常的地方
    以及如果确实发生异常,控制权在哪里。

    如果您仔细检查大多数语言,它们也会
    明确表达式中计算值的排序,
    如果表达式中有两个副作用,这将很重要;
    控制流应反映顺序(或非顺序,
    (如果未定义)。

    也许您只想要控制流的抽象
    具有基本的块和条件。那是
    显然容易一些。

    无论哪种情况(简单CFG或完整CFG),您都需要使用AST,
    在每个点上都参考可能的控制流目标
    (例如,在大多数情况下,例如IF语句,有两个流目标:
    THEN和ELSE子句)。在每个节点上,将该节点链接到
    适当的控制流量目标,可能会替换流量目标
    (例如,遇到IF时)。

    对于Java(或C)的完整语言语义而言,做到这一点相当
    很多工作。您可能只想使用一种工具来计算
    现成的。
    参见http://www.semanticdesigns.com/Products/DMS/FlowAnalysis.html
    从我们的工具中获得真正的效果。


    根据一些评论,听起来OP确实想进行代码生成-将AST转换为基于基本块和跳转点的较低级指令序列。

    代码生成是非常特定于语言的,并且在此主题中进行了大量工作。在进行代码生成之前,您需要了解目标语言-无论是汇编语言还是其他某种高级语言。一旦确定了这一点,您只需要遍历AST并生成在AST中实现代码的指令序列。 (我说这很简单,但是可能很难-很难一概而论,因为此处的注意事项是特定于语言的。)

    您选择用于代码生成的表示形式将隐式或显式包含控制流图。如果您的目标语言相当低级(接近汇编语言),则控制流图应该相对容易提取。

    (如果需要进一步说明,请发表评论。)


    我认为我无法以您可能正在寻找的方式回答您的问题,因为我不知道在ANTLR中以任何方式生成带有或不带有AST的CFG。但是,简而言之,您将使用ANTLR生成的内容来生成单独的Java程序来生成CFG。您将利用ANTLR生成的语法树作为输入,以在自己创建的单独Java程序中生成CFG。从本质上讲,这时您正在构建编译器。您的"编译器"和JVM之间的区别在于,您的输出是程序如何分支其各种执行路径的可视化表示(CFG),而JVM / Java编译器生成了在真实机器(CPU)上执行的代码。

    打个比方,如果有人坐下来写书(例如,用英语),句子中使用的单个单词是计算机语言的令牌,句子的形成方式类似于上下文无关的语法表示有效的计算机代码,而段落整本小说都以类似的方式讲述一个故事,即语义分析/编译器/ CFG可能会生成/表示逻辑上有效的程序,这些程序实际上在做有用的事情,或多或少没有逻辑错误。换句话说,一旦您克服了有效语法(正确的句子结构)的问题,任何人都可以在页面上写下一堆句子,但是只有某些句子组合才能产生出确实可以起到作用的文本(讲述一个故事)。

    您要问的是最后一部分-如何进行语法树转换和解释AST在逻辑上的实际作用。当然,您需要为每种语言构建一个"编译器"。拥有正确的语法并不能告诉您程序的功能-只是从语法角度来看程序是正确的。

    Linter和语法突出显示器以及IDE都是基于这样的想法构建的,即试图使难题的最后一部分对人类来说变得更容易,更有效。


    过去完成此操作时,我使用了graphviz(尤其是点工具)来生成图形。我通过在编译时实际遍历控制流图来创建点输入文件。

    图的布局是一个难题,graphviz做得很好。它可以输出为ps,pdf和各种图像格式,并且布局通常很直观。我强烈推荐它。


    您是否尝试过ANTLR Studio?它不会生成孔AST图,但是对于回顾来说,它已经非常有用。


    推荐阅读

      linux中断命令语句?

      linux中断命令语句?,系统,服务,状态,号码,进程,命令,信号,传播,互动,名称,在l

      写5条linux命令语句?

      写5条linux命令语句?,工作,地址,系统,信息,目录,命令,管理,标准,功能,文件,li

      linux命令语句规律?

      linux命令语句规律?,系统,管理,基础,网络,信息,命令,服务,简介,工具,标准,lin

      linux循环语句命令?

      linux循环语句命令?,地方,增长,数字,语句,流程,名称,工具,代码,数据,条件,Lin

      嵌入式linux命令语句?

      嵌入式linux命令语句?,系统,环境,基础,网络,软件,基础知识,服务,设备,管理,

      Python 条件语句

      Python 条件语句,代码,语句,条件,名称,培训,信息,位置,结果,变量,括号,Pytho

      Python单条语句计时

      Python单条语句计时,工具,对比,分析,时间,入口,标准,位置,网络,数据,培训,上

      Python 基本语句

      Python 基本语句,培训,语句,条件,结果,逻辑,字符串,序列,完整性,事情,以上,1

      Python 抽象类

      Python 抽象类,数据,设计,概念,培训,方法,定义,属性,接口,功能,内容,1.什么

      python 抽象类

      python 抽象类,数据,概念,设计,培训,方法,定义,功能,内容,水果,桃子,什么是

      python 抽象类和接口类

      python 抽象类和接口类,支付,设备,设计,网络,代码,概念,培训,接口,细节,对

      python 的条件判断语句

      python 的条件判断语句,代码,培训,语句,条件,冒号,整数,序列,函数,逻辑,元

      python中有跳转语句吗?

      python中有跳转语句吗?,培训,语句,桔子,继续,嵌套,条件下,剩余,表示,结果,

      python里的if语句怎么写

      python里的if语句怎么写,标准,培训,情况,左侧,右侧,语句,两侧,根据,结构,写

      python语句加分号吗

      python语句加分号吗,代码,培训,分号,语句,以上,时候,建议,更多,内容,python