Warning: Undefined global variable $debug in /var/www/ourcoders/tiny4cocoa/application/controllers/baseController.php on line 124
左耳朵耗子 2019-09-25 09:49:10 发布的技术动态 - OurCoders (我们程序员)
左耳朵耗子
2019-09-25 09:49:10 发布
接上一条微博说说怎么找重复功能的代码,权当是闲扯科普一下了(因为看到很多人并没有一个清楚的认识,然后就开喷)其一,现在的代码分析工具如Sonar之类的都会查找代码中的重复代码,这些静态分析工具的底层主要使用到的库是一个是PMD(Programming Mistake Detector)的开源库 网页链接 ,这个库用到的查找重复代码一个lib叫CPD(Copy/Paste Detector),他们用到的算法主要是 Rabin–Karp 字符串搜索算法,所以,本质上只是在做文本比较,不是语法比较。所以,如果只是文本比较,可以做diff,然后统计diff的不一样的的程度。(毕竟现在的程序员不都是从StackOverflow/Github上抄代码吗?嘿嘿嘿)其二,再高级一点的,需要建立词法分析,通过词法分析识别特征以及pattern,然后比较这些特征。词法分析是把字符串转成标识符(token)的方式,这样可以识别到因为代码结构相同,但是变量名不同的代码。其三,再往上,需要建立语法分析,也就是抽象语法树AST(Abstract Sytanx Tree),一般来说IDE为了提前查错都要干这个事,所以,相关的代码可以从IDE里找,比如:Eclipse的ASTParser。然后需要对AST做diff。做AST diff的一个开源项目是 GumTree(网页链接),还可以把树图示出来。其四,你千万不要觉得语法分析树就是最优解了,其实并不是,因为词法分析和语法分析在好些情况下可能还不如文本分析,为什么?因为如果我的一段代码中全是函数调用,词法和语法分析是没什么用的。词法和语法相似并不能说明功能相似。这个因果关系,学过编译原理的应该都清楚。其五,所以,再高级一点就是在执行上相似,毕竟语法相似可能执行起来不相似,所以,最好能够在分析程序员的执行流程和函数调用树,这个事就是相当的复杂和需要超级多的计算。同时也不要以为流程上相似,代码的功能相似。这些东西其实并没有完全严格的因果关系。其六,如果要做好话,文本比较可能在复杂度、执行性能和效果上可能会更好一些。当然,可能需要混合上述的方式,会更有效,但是,可以预见的是,无论你怎么组合,在某些情况下也不行。