【发布时间】:2016-11-11 10:09:14
【问题描述】:
我很难理解
1) AST 匹配,两个 AST 有什么相似之处?比较/匹配中是否包含类型或仅包含 +、-、++、...等操作?
2) 两个语句在句法上相似(这个术语我在一篇论文的某处读到过),我们可以说下面的例子中两个语句在句法上相似吗?
int x = 1 + 2
String y = "1" + "2"
Java - Eclipse 是目前正在使用并试图理解 AST 的。
最好的问候,
【问题讨论】:
我很难理解
1) AST 匹配,两个 AST 有什么相似之处?比较/匹配中是否包含类型或仅包含 +、-、++、...等操作?
2) 两个语句在句法上相似(这个术语我在一篇论文的某处读到过),我们可以说下面的例子中两个语句在句法上相似吗?
int x = 1 + 2
String y = "1" + "2"
Java - Eclipse 是目前正在使用并试图理解 AST 的。
最好的问候,
【问题讨论】:
什么是 AST:
AST 是一种表示程序源文本的数据结构,它由包含 node 类型的节点和可能的字面值以及子节点列表组成。节点类型对应于 OP 所谓的“操作”(+、-、...),但还包括语言命令(do、if、assignment、call、...)、声明(int、struct、...)和文字(数字、字符串、布尔值)。 [不清楚 OP 的“类型”是什么意思]。 (AST 通常在每个节点中都有附加信息,这些信息指的是源文本文件中的原点)。
AST 的用途:
OP 似乎对 Eclipse 中存在 AST 感到困惑。
AST 用于以比原始文本更容易解释的形式表示程序文本。它们提供了一种推理程序结构或内容的方法;有时它们用于通过修改程序的 AST 然后从 AST 重新生成文本来启用程序的修改(“重构”)。
根据我的经验,比较 AST 的相似性并不是一个真正常见的用途,除了克隆检测和/或模式匹配。
比较 AST:
比较 AST 是否相等很容易:比较根节点类型/文字值是否相等;如果不相等,则比较完成,否则(递归地)比较子节点)。
比较相似性的 AST 比较困难,因为您必须决定如何放松等式比较。 特别是,您必须确定相似性的精确定义。有很多方法可以定义它,一些在语法上相当浅显,一些在语义上更复杂。
我的论文Clone Detection Using Abstract Syntax Trees 描述了一种方法,使用相似性定义为共享的节点数除以两棵树中的总节点数之比。共享节点是通过将树自上而下与某个子节点不同的点进行比较来计算的。 (实际的比较是计算一个反统一符)。这种相似的度量相当肤浅,但在查找大型软件系统中的代码克隆时效果非常好。
从这个角度来看,OP 的例子:
int x = 1 + 2
String y = "1" + "2"
将树写成 S 表达式:
(declaration_with_assignment (int x) (+ 1 2))
(declaration_with_assignment (String y) (+ "1" "2"))
这些不是很相似;它们只共享一个类型为“declaration-with-assignment”的根节点和 + 子树的顶部。 (这里的节点数为 12,只有 2 个匹配节点,相似度为 2/12)。
这些会更相似:
int x = 1 + 2
float x = 1.0 + 2
(S-表达式)
(declaration_with_assignment (int x) (+ 1 2))
(declaration_with_assignment (float x) (+ 1.0 2))
它与赋值、添加节点、文字叶节点 2 以及整数 1 和浮点 1.0 的文字节点共享声明,这取决于您是否希望将它们定义为“相等”,以实现相似性4/12。
如果您将其中一棵树更改为模式树,其中一些“叶子”是模式变量,那么您可以使用此类模式树来查找具有特定结构的代码。
表面语法模式:
?type ?variable = 1 + ?expression
带有 S 表达式
((declaration_with_assignment (?type ?varaible)) (+ 1 ?expression))
匹配 OP 的第一个示例,但不匹配第二个。
据我所知,Eclipse 不提供任何基于模式的匹配功能。 但是这些在程序分析和/或程序转换工具中非常有用。一些具体的例子,太长了,这里就不一一列举了,见DMS Rewrite Rules
(完全披露:DMS 是我公司的产品。我是架构师)。
【讨论】: