2010-12-19 69 views
6

我试图弄清楚如何实现我的LEParserCfgVisitor类,以从已经用JavaCC生成的Abstract-Syntax-Tree构建控制流图。我知道有些工具已经存在,但我正在为编译器决赛做准备。从一个使用Java访问者模式的AST构建控制流图来源:

我知道我需要一个数据结构来保持图形在内存中,我希望能够在每个节点中保留像IN,OUT,GEN,KILL这样的属性,以便能够执行控制流稍后分析。

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

这是我空的访客。你可以看到它的工作原理基本langage表达,就像如果同时和基本操作(+, - ,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) { 
    } 
} 

谁能给我个忙吗?

谢谢!

回答

11

要做关于数据流的推理(gen/kill/use/def),你首先需要一个控制流图。为了构建一个,在每个树节点(例如,在每个特定节点访问者内部),构建该节点表示的图的片段;将该图的入口点弧和出口弧传递给父“访客”。纯粹独立的访问者将无法工作,因为您需要将信息传递给父母。 [您可以为访问者设置的每个节点添加入口/出口弧槽,并由父节点进行检查。]

某些节点(例如,“assignmentstmt”)将制作一个引用AST的动作节点,分配(在流程图中认为“矩形”);没有任何子图弧担心。一些节点(例如,“if”)将制造一个条件分支节点(为条件表达式引用AST节点),(在流程图中认为是“菱形”),一个流联接节点,并且组成一个结构化(if- then-else)子图通过将该条件分支节点与then和else子句(仅由入口和出口圆弧表示)的子图组合在一起,与流join-node一起使用。然后将该入口和出口圆弧传递给该复合子图。

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

请记住担心异常;他们也是GOTO,但通常在结构化控制流程图中更高一点。这些通常是通过将树的最内层异常处理程序节点传递给来处理的;现在你的访问者需要看看up树看最新的异常处理程序。

使用生成的访问者的更复杂的方案称为http://en.wikipedia.org/wiki/Attribute_grammar">属性语法,它基本上为您管理所有信息流,方法是将感兴趣的值在这种情况下,入口/出口/异常流程会以参数和结果的形式在树中上下移动,您需要一个属性语法工具来执行此操作;您仍然必须指定节点构建逻辑。我们使用属性语法和基本上与我们的DMS Software Reengineering Toolkit一块件的上述控制流程图结构来为许多语言提供通用控制流分析工具。

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

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

关于一般过程的更多细节可以参考here