使用 Java 通过访问者模式从 AST 构建控制流图

发布于 2024-10-08 07:52:40 字数 1675 浏览 6 评论 0原文

我试图弄清楚如何实现我的 LEParserCfgVisitor 类,以便从已使用 JavaCC 生成的抽象语法树构建控制流图。我知道已经存在一些工具,但我正在尝试这样做,为我的编译器期末考试做准备。

我知道我需要一个将图形保存在内存中的数据结构,并且我希望能够在每个节点中保留 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) {
  }
}

有人可以帮我吗?

谢谢!

I'm trying to figure out how to implement my LEParserCfgVisitor class as to build a control-flow graph from an Abstract-Syntax-Tree already generated with JavaCC. I know there are tools that already exist, but I'm trying to do it in preparation for my Compilers final.

I know I need to have a data structure that keeps the graph in memory, and I want to be able to keep attributes like IN, OUT, GEN, KILL in each node as to be able to do a control-flow analysis later on.

My main problem is that I haven't figured out how to connect the different blocks together, as to have the right edge between each blocks depending on their nature: branch, loops, etc. In other words, I haven't found an explicit algorithm that could help me build my visitor.

Here is my empty Visitor. You can see it works on basic langage expressions, like if, while and basic operations (+,-,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) {
  }
}

Can anyone give me a hand?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

白鸥掠海 2024-10-15 07:52:40

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

为了构建一个,在每个树节点(例如,在每个特定节点访问者内部),构建该节点表示的图的一部分;将该图的入口点弧和出口弧传递给父“访问者”。纯粹的独立访客是行不通的,因为你需要向家长传递信息。 [您可以将入口/出口弧槽添加到由访问者设置并由父级检查的每个节点。]

某些节点(例如,对于“assignmentstmt”)将创建一个引用 AST 进行分配的操作节点(认为流程图中的“矩形”);没有任何子图弧需要担心。一些节点(例如,“if”)将创建一个条件分支节点(引用条件表达式的 AST 节点)(想想流程图中的“菱形”)、一个流连接节点,并组成一个结构化的(if- then-else)子图,通过将条件分支节点与 then 和 else 子句的子图(仅由 then 入口和出口弧表示)与流连接节点组合起来。然后,将此复合子图的入口和出口弧传递给父级。

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

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

使用生成的访问者的更复杂的方案称为 http://en.wikipedia.org/wiki/Attribute_grammar"> 属性语法,它本质上通过传递感兴趣的值(在本例中)来为您管理所有信息流,进入/退出/异常流弧)作为参数和结果在树中上下移动,您需要一个属性语法工具来执行此操作,并且您仍然需要指定节点构建逻辑,并且本质上是上述控制流。使用我们的DMS 软件重新工程工具包分段构建图形,以提供通用控制流分析工具对于许多语言。

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

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

有关一般流程的更多详细信息,请参阅此处

To do reasoning about data flows (gen/kill/use/def) you first need a control flow graph.

To construct one, at each tree node (e.g., inside each specific node visitor), build the piece of the graph that the node represents; pass the entry point arc and the exit arc for that graph to the parent "visitor". Purely independent vistors won't work because you need to pass information to parents. [You could add entry/exit arcs slots to each node that are set by the visitor, and inspected by the parent.]

Some nodes (e.g., for "assignmentstmt") will manufacture an action node referring to the AST for the assignment (think "rectangle" in a flowchart); there aren't any subgraph arcs to worry about. Some nodes (e.g., for "if") will manufacture a conditional branch node (referencing the AST node for the condition expression), (think "diamond" in a flowchart), an flow-join node, and compose a structured (if-then-else) subgraph by combining that conditional branch node with the subgraphs for the then and else clauses (represented just by then entry and exit arcs), with the flow join-node. You then pass the entry and exit arcs to this compound subgraph to the parent.

This scheme works with structured control flow. Unstructured control flow (e.g, "GOTO x") requires some funny adjustments, e.g, first building the structured part of the graph, associating generated control flow with labels, and then going back and patcing the GOTO actions to have an arc to the associated label.

Remember to worry about exceptions; they are GOTOs too, but generally to a point higher in the structured control flow graph. These are often handled by passing the innermost exception handler node down the tree; now your visitors need to look up the tree to see that most recent exception handler.

A more sophisticated scheme that uses generated vistors is called an http://en.wikipedia.org/wiki/Attribute_grammar">attribute grammar, which essentially manages all the information flows for you, by passing the values of interest (in this case, entry/exit/exception flow arcs) up and down the tree as parameters and results. You need an attribute grammar tool to do this; and you still have to specify node-building logic. We use attribute grammars and essentially the above control flow graph construction by pieces with our DMS Software Reengineering Toolkit to provide generic control flow analysis facilities for many languages.

Once you have the control flow graph, then you can implement a data flow solver of the type you describe by walking over the control flow graph. You'll need to re-visit the ASTs that the CF nodes point-to to collect the raw use/raw def information.

If your langauge has only structured control flow, then you can use the ASTs nodes to represent the control flow nodes, and compute the data flow directly.

More details on the general process can be found here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文