【问题标题】:Building CFGs from the AST从 AST 构建 CFG
【发布时间】:2016-09-28 11:45:49
【问题描述】:

据我所知,在解析器构建 AST 后,此结构将转换为“中级”IR,例如三个地址代码或任何其他代码。然后,为了执行一些分析,这个 IR 被转换成一个控制流图。我的问题是,是否有可能在不通过另一个 IR 的情况下从 AST 表示转到 CFG,然后通过 CFG 执行例如数据流分析并获得成功的结果?

【问题讨论】:

    标签: transformation abstract-syntax-tree analysis


    【解决方案1】:

    如果不先进行作用域再进行名称解析,就无法构造 CFG。

    您需要范围解析来确定隐式控制转移的“范围”,例如 if-then-else、try-statement、带有“break statements”的块、return 语句等的边界。这通常是相当容易,因为作用域倾向于遵循语言的语法结构,而您已经拥有 AST。

    如果您的语言允许控制转移到命名实体(“goto”)、“call”,您还需要范围解析以确定标识符的定义位置。如果不知道哪个范围包含 goto,以及范围如何控制命名标签的查找,您就无法知道哪个 goto 目标。

    通过范围解析,您可以实现名称解析;这允许您将名称分配给包含它们的定义范围,并附加名称的定义(例如,知道“goto x”指的是特定范围内的 x,因此指向在该范围内定义 x 的第 750 行.

    一旦您有了名称解析(这样您就可以在“goto x”中查找 x 的定义),现在您可以构建一个控制流图。

    您可以使用属性语法来完成所有这三个操作,这本质上是直接在 AST 上的计算。所以,不,除了 AST 之外,你不需要任何东西来实现这些。 {您可以了解更多关于属性计算的信息at my SO answer describing them。当然,你可以通过形式属性计算来做任何事情,你也可以通过简单地编写大量遍历树并计算等效结果的递归过程来完成;这就是属性语法在实践中的编译方式。

    在这里你可以找到some details on how to extract the control flow graph by attribute computation

    一个混乱的故障是像“goto @”这样的计算(GCC 允许这样做)。要做到这一点正确,您需要计算标签变量的数据流(从技术上讲,这需要您首先构建 CFG :-( )。您可以通过构建保守的答案来避免执行数据流:“ goto @" 可以转到任何在找到 goto 的函数中获取地址的标签。您也可以使用属性语法来计算它。

    对于只有结构化控制流的语言,其实可以通过属性语法直接实现数据流分析。

    【讨论】:

    • 首先,非常感谢您提供详细而有用的答案。我想我已经明白你所说的了。但是,我对范围和名称解析的实施有一些疑问。我认为它是每个范围的数据结构,然后在其中包含属于该特定范围的结构。正如您在答案中所说,我可以提取其特定范围,因为 AST 的结构。我可能迷路了?
    • 每个范围抽象地是从任意一组程序位置到在该范围内定义的一组标识符定义的映射。在许多语言中(也许是你的,也许不是),范围的“程序位置集”总是对应于 AST 的子树;在这种语言中,作用域倾向于在词法上嵌套。 (具有“命名空间”结构的语言打破了实例命名空间的这条规则)。对于这样的语言,很容易识别范围;它们对应于“参数列表”、“块体”等树节点……我不认为你迷路了。
    • 我正在解析的语言是 C,我认为它尊重你所说的规则。再次感谢您的回答,对我有很大帮助。
    猜你喜欢
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    • 2019-05-25
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多