教你如何用AST语法树对代码“动手脚”-创新互联
作为程序猿,每天都在写代码,但是有没有想过通过代码对写好的代码”动点手脚”呢?今天就与大家分享——
创新互联专注于企业成都全网营销、网站重做改版、蚌埠网站定制设计、自适应品牌网站建设、H5技术、成都商城网站开发、集团公司官网建设、成都外贸网站制作、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为蚌埠等各大城市提供网站开发制作服务。先抛一个问题:如何将图一代码改写为图二?
此题需要把代码中和程序逻辑无关的字符串提取出来,替换为id。比如个推日志输出类,缩短日志描述信息后,输出的日志就随之变短,根据映射表可以恢复真实原始日志。
通过何种方案改写?
你可能会想通过万能的“正则表达式”匹配替换,但当代码较为复杂时(如下图所示),使用“正则表达法”则会将问题复杂化,难以确保所有代码的完美覆盖并匹配。若通过AST语法树,可以很好地解决此问题。
什么是AST语法树?
AST(Abstract syntax tree)即为“抽象语法树”,简称语法树,指代码在计算机内存的一种树状数据结构,便于计算机理解和阅读。
一般只有语言的编译器开发人员或者从事语言设计的人员才涉及到语法树的提取和处理,所以很多人会对这个概念比较陌生。
上图即为语法树,左边树的节点对应右边相同颜色覆盖的代码块。
众所周知,Java 编译流程(上图)中也有对AST语法树的提取处理,那是否可以在此环节操作语法树呢?由于编译链代码栈太深,鲜有对外的接口和文档,使得其可操作性不强。不过,如果采用迂回战术如下图所示,可以对其进行操作。
个推log-rewrite项目改写日志,就是用AST语法树进行的,流程图如下图所示。
先把所有源码解析为AST语法树,遍历每一个编译单元与单元的类声明,在类声明里根据日志方法的签名找到所有的方法调用,然后遍历每个方法调用,将方法调用的第二个参数表达式放入递归方法,对字符串字面值进行改写。
对应的代码较为简短, 使用github的 Netflix-Skunkworks/rewrite开源库与kotlin语言,能读懂Java的你也一定能读明白。
如果想将日志恢复原样,可根据前缀、后缀定制正则表达式,逐行匹配替换。如下图所示。
AST有哪些应用场景?
1、 编译工具从ant到gradle的切换
此项目起步于ant主流时期,随着技术日渐成熟,gradle逐渐取代了ant的位置,演变成官方的编译打包方式。因为历史原因,若直接将上图类似预编译的代码切换到gradle较为棘手,通过AST语法树重写,再用gradle编译,就可以解决此问题。
上图的#debug和#mdebug指令,也可以通过AST改写之后再进行编译。
2、 自动静态埋点
代码中需要运营统计、数据分析等,需要通过代码埋点进行用户行为数据收集。传统的做法是手动在代码中添加埋点代码,但此过程较为繁琐,可能会对业务代码造成干扰,倘若通过改写AST语法树,在编译打包期添加这种类似的埋点代码,就可减少不必要的繁琐过程,使其更加高效。
最后附推荐操作AST类库链接&完整项目源码地址,希望可以帮助大家打开脑洞,设想更多的应用场景。
推荐操作AST类库链接
https://github.com/Netflix-Skunkworks/rewrite
https://github.com/Javaparser/Javaparser
https://github.com/antlr/antlr4
完整项目源码地址如下,欢迎fork&start
https://github.com/foxundermoon/log-rewrite
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
文章题目:教你如何用AST语法树对代码“动手脚”-创新互联
网页地址:http://azwzsj.com/article/doeojc.html