【发布时间】:2016-09-28 11:45:49
【问题描述】:
据我所知,在解析器构建 AST 后,此结构将转换为“中级”IR,例如三个地址代码或任何其他代码。然后,为了执行一些分析,这个 IR 被转换成一个控制流图。我的问题是,是否有可能在不通过另一个 IR 的情况下从 AST 表示转到 CFG,然后通过 CFG 执行例如数据流分析并获得成功的结果?
【问题讨论】:
标签: transformation abstract-syntax-tree analysis
据我所知,在解析器构建 AST 后,此结构将转换为“中级”IR,例如三个地址代码或任何其他代码。然后,为了执行一些分析,这个 IR 被转换成一个控制流图。我的问题是,是否有可能在不通过另一个 IR 的情况下从 AST 表示转到 CFG,然后通过 CFG 执行例如数据流分析并获得成功的结果?
【问题讨论】:
标签: transformation abstract-syntax-tree analysis
如果不先进行作用域再进行名称解析,就无法构造 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 的函数中获取地址的标签。您也可以使用属性语法来计算它。
对于只有结构化控制流的语言,其实可以通过属性语法直接实现数据流分析。
【讨论】: