使用Java从具有访问者模式的AST构建控制流图

时间:2010-12-19 16:15:59

标签: java abstract-syntax-tree visitor-pattern control-flow

我正在试图弄清楚如何实现我的LEParserCfgVisitor类,以便从已经使用JavaCC生成的Abstract-Syntax-Tree构建控制流图。我知道有一些工具已经存在,但我正在努力为我的编译器决赛做准备。

我知道我需要有一个数据结构将图形保存在内存中,我希望能够在每个节点中保留IN,OUT,GEN,KILL等属性,以便能够进行控制流分析以后。

我的主要问题是我还没弄明白如何将不同的块连接在一起,因为每个块之间的边缘取决于它们的性质:分支,循环等。换句话说,我没有找到了一个可以帮助我建立访问者的明确算法。

这是我的空访客。你可以看到它适用于基本的语言表达式,比如if,while和基本操作(+, - ,x,^,...)

public class LEParserCfgVisitor implements LEParserVisitor
{
  public Object visit(SimpleNode node, Object data) { return data; }

  public Object visit(ASTProgram node, Object data) { 
    data = node.childrenAccept(this, data);
    return data; 
  }

  public Object visit(ASTBlock node, Object data) {
  }

  public Object visit(ASTStmt node, Object data) {
  }

  public Object visit(ASTAssignStmt node, Object data) {
  }

  public Object visit(ASTIOStmt node, Object data) { 
  }

  public Object visit(ASTIfStmt node, Object data) {
  }

  public Object visit(ASTWhileStmt node, Object data) {
  }

  public Object visit(ASTExpr node, Object data) { 
  }

  public Object visit(ASTAddExpr node, Object data) {
  }

  public Object visit(ASTFactExpr node, Object data) {
  }

  public Object visit(ASTMultExpr node, Object data) { 
  }

  public Object visit(ASTPowerExpr node, Object data) {  
  }

  public Object visit(ASTUnaryExpr node, Object data) { 
  }

  public Object visit(ASTBasicExpr node, Object data) {
  }

  public Object visit(ASTFctExpr node, Object data) {
  }

  public Object visit(ASTRealValue node, Object data) { 
  }

  public Object visit(ASTIntValue node, Object data) { 
  }

  public Object visit(ASTIdentifier node, Object data) {
  }
}

任何人都可以帮我一把吗?

谢谢!

1 个答案:

答案 0 :(得分:11)

要对数据流进行推理(gen / kill / use / def),首先需要一个控制流图。

在每个树节点(例如,在每个特定节点访问者内部)构建一个节点,构建节点所代表的图形片段;将该图形的入口点弧和出口弧传递给父“访问者”。纯粹独立的游客将无法工作,因为您需要将信息传递给父母。 [您可以向访客设置的每个节点添加进入/退出弧槽,并由父级进行检查。]

一些节点(例如,用于“assignmentstmt”)将制作一个动作节点,该动作节点引用用于分配的AST(在流程图中认为“矩形”);没有任何子图弧需要担心。一些节点(例如,用于“if”)将制造条件分支节点(引用条件表达式的AST节点),(在流程图中认为“菱形”),流连接节点,并组成结构化的(如果 - 那么 - 其他)子图通过将该条件分支节点与then和else子句的子图(由当时的入口和出口弧表示)与流连接节点组合在一起。然后,您将进入和退出弧线传递给此复合子图形到父级。

此方案适用于结构化控制流程。非结构化控制流(例如,“GOTO x”)需要一些有趣的调整,例如,首先构建图形的结构化部分,将生成的控制流与标签相关联,然后返回并修改GOTO动作以使弧形成相关联标签。

记得担心例外;它们也是GOTO,但通常在结构化控制流程图中更高一点。这些通常是通过将最里面的异常处理程序节点向下传递树来处理的;现在,您的访问者需要查看 up 树以查看最新的异常处理程序。

使用生成的命令的更复杂的方案称为http://en.wikipedia.org/wiki/Attribute_grammar">attribute语法,它通过传递感兴趣的值来基本管理所有信息流(在这种情况下,进入/退出/异常流作为参数和结果在树上上下移动。你需要一个属性语法工具来做这个;你仍然需要指定节点构建逻辑。我们使用属性语法,基本上是以上控制流程图使用我们的DMS Software Reengineering Toolkit按件构建,以便为多种语言提供通用控制流分析功能。

获得控制流图后,您可以通过遍历控制流图来实现所描述类型的数据流解算器。您需要重新访问CF节点指向的AST来收集原始使用/原始def信息。

如果您的语言只有 结构化控制流,那么您可以使用ASTs节点来表示控制流节点,并直接计算数据流。

有关常规流程的更多详细信息,请参见here

相关问题