工作日志
1. 代码生成AST
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void getAst()
{
string str;
system("gcc test.c -fdump-tree-original-raw");
}
int main()
{
getAst();
return 0;
}
test.c代码如下:
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("hello world");
return 0;
}
运行后获取的结果部分如下:
;; Function __debugbreak (null)
;; enabled by -tree-original
@1 bind_expr type: @2 body: @3
@2 void_type name: @4 algn: 8
@3 asm_expr type: @2
@4 type_decl name: @5 type: @2
@5 identifier_node strg: void lngt: 4
;; Function vfscanf (null)
;; enabled by -tree-original
@1 bind_expr type: @2 body: @3
@2 void_type name: @4 algn: 8
@3 return_expr type: @2 expr: @5
@4 type_decl name: @6 type: @2
@5 modify_expr type: @7 op 0: @8 op 1: @9
@6 identifier_node strg: void lngt: 4
@7 integer_type name: @10 size: @11 algn: 32
prec: 32 sign: signed min : @12
max : @13
@8 result_decl type: @7 scpe: @14 srcp: stdio.h:545
note: artificial size: @11
algn: 32
@9 call_expr type: @7 fn : @15 0 : @16
1 : @17 2 : @18
@10 type_decl name: @19 type: @7
@11 integer_cst type: @20 int: 32
@12 integer_cst type: @7 int: -2147483648
@13 integer_cst type: @7 int: 2147483647
@14 function_decl name: @21 type: @22 srcp: stdio.h:545
args: @16 link: static
@15 addr_expr type: @23 op 0: @24
@16 parm_decl name: @25 type: @26 scpe: @14
srcp: stdio.h:545 argt: @26
size: @27 algn: 64 used: 1
@17 parm_decl name: @28 type: @29 scpe: @14
srcp: stdio.h:545 argt: @29
size: @27 algn: 64 used: 1
@18 parm_decl name: @30 type: @31 scpe: @14
srcp: stdio.h:545 argt: @31
size: @27 algn: 64 used: 1
@19 identifier_node strg: int lngt: 3
@20 integer_type name: @32 size: @33 algn: 128
prec: 128 sign: unsigned min : @34
max : @35
@21 identifier_node strg: vfscanf lngt: 7
@22 function_type size: @36 algn: 8 retn: @7
prms: @37
@23 pointer_type size: @27 algn: 64 ptd : @38
@24 function_decl name: @39 type: @38 srcp: stdio.h:539
args: @40 body: undefined
link: extern
@25 identifier_node strg: __stream lngt: 8
@26 pointer_type size: @27 algn: 64 ptd : @41
@27 integer_cst type: @20 int: 64
@28 identifier_node strg: __format lngt: 8
@29 pointer_type size: @27 algn: 64 ptd : @42
@30 identifier_node strg: __local_argv lngt: 12
@31 pointer_type name: @43 unql: @44 size: @27
algn: 64 ptd : @45
@32 identifier_node strg: bitsizetype lngt: 11
@33 integer_cst type: @20 int: 128
@34 integer_cst type: @20 int: 0
@35 integer_cst type: @20 int: -1
@36 integer_cst type: @20 int: 8
@37 tree_list valu: @26 chan: @46
@38 function_type size: @36 algn: 8 retn: @7
prms: @47
@39 identifier_node strg: __ms_vfscanf lngt: 12
@40 parm_decl name: @48 type: @49 srcp: stdio.h:539
argt: @49 size: @27 algn: 64
used: 0
@41 record_type name: @50 unql: @51 size: @52
algn: 64 tag : struct flds: @53
@42 integer_type qual: c name: @54 unql: @45
size: @36 algn: 8 prec: 8
sign: signed min : @55 max : @56
@43 type_decl name: @57 type: @31
@44 pointer_type name: @58 size: @27 algn: 64
ptd : @45
@45 integer_type name: @54 size: @36 algn: 8
prec: 8 sign: signed min : @55
max : @56
@46 tree_list valu: @29 chan: @59
@47 tree_list valu: @49 chan: @60
@48 identifier_node strg: fp lngt: 2
@49 pointer_type qual: r unql: @26 size: @27
algn: 64 ptd : @41
@50 type_decl name: @61 type: @41 srcp: stdio.h:36
@51 record_type name: @62 size: @52 algn: 64
tag : struct flds: @53
@52 integer_cst type: @20 int: 384
@53 field_decl name: @63 type: @64 scpe: @51
srcp: stdio.h:27 size: @27
algn: 64 bpos: @34
@54 type_decl name: @65 type: @45
@55 integer_cst type: @45 int: -128
@56 integer_cst type: @45 int: 127
@57 identifier_node strg: __builtin_va_list lngt: 17
@58 type_decl name: @66 type: @44
@59 tree_list valu: @31 chan: @67
@60 tree_list valu: @68 chan: @69
@61 identifier_node strg: FILE lngt: 4
@62 identifier_node strg: _iobuf lngt: 6
@63 identifier_node strg: _ptr lngt: 4
@64 pointer_type size: @27 algn: 64 ptd : @45
@65 identifier_node strg: char lngt: 4
@66 identifier_node strg: __builtin_ms_va_list lngt: 20
@67 tree_list valu: @2
@68 pointer_type qual: r unql: @29 size: @27
algn: 64 ptd : @42
@69 tree_list valu: @70 chan: @67
@70 pointer_type name: @71 unql: @44 size: @27
algn: 64 ptd : @45
@71 type_decl name: @72 type: @70 srcp: vadefs.h:31
@72 identifier_node strg: va_list lngt: 7
2. 代码获取规范化AST
主要是去除一些空格和无意义的符号
3. 基于AST抽象语法树的程序源码相似度检测算法归纳
一些常见的代码相似度检测算法基于AST包括:
树形编辑距离算法:它通过比较两个AST树的结构差异来计算相似度。
哈希算法:它通过对AST树中每个节点的信息进行哈希计算,并对比两个AST树的哈希值以评估相似度。
字符串匹配算法:它通过将AST树转换为字符串表示,并对比两个字符串的相似度评估代码相似度。
节点相似性算法:它通过评估两个AST树中节点的相似性来评估相似度。
这些算法的具体实现可能因语言、平台和应用场景的不同而有所变化,但基本思路是相通的。