91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

教你如何用AST語法樹對代碼“動手腳”

發布時間:2020-07-12 14:14:22 來源:網絡 閱讀:1659 作者:個推 欄目:開發技術

作為程序猿,每天都在寫代碼,但是有沒有想過通過代碼對寫好的代碼”動點手腳”呢?今天就與大家分享——

 

先拋一個問題:如何將圖一代碼改寫為圖二?


 教你如何用AST語法樹對代碼“動手腳”

 教你如何用AST語法樹對代碼“動手腳”

此題需要把代碼中和程序邏輯無關的字符串提取出來,替換為id。比如個推日志輸出類,縮短日志描述信息后,輸出的日志就隨之變短,根據映射表可以恢復真實原始日志。


通過何種方案改寫?


你可能會想通過萬能的“正則表達式”匹配替換,但當代碼較為復雜時(如下圖所示),使用“正則表達法”則會將問題復雜化,難以確保所有代碼的完美覆蓋并匹配。若通過AST語法樹,可以很好地解決此問題。

 教你如何用AST語法樹對代碼“動手腳”


什么是AST語法樹?


AST(Abstract syntax tree)即為“抽象語法樹”,簡稱語法樹,指代碼在計算機內存的一種樹狀數據結構,便于計算機理解和閱讀。

 教你如何用AST語法樹對代碼“動手腳”

一般只有語言的編譯器開發人員或者從事語言設計的人員才涉及到語法樹的提取和處理,所以很多人會對這個概念比較陌生。

 教你如何用AST語法樹對代碼“動手腳”

上圖即為語法樹,左邊樹的節點對應右邊相同顏色覆蓋的代碼塊。

 教你如何用AST語法樹對代碼“動手腳”

眾所周知,Java 編譯流程(上圖)中也有對AST語法樹的提取處理,那是否可以在此環節操作語法樹呢?由于編譯鏈代碼棧太深,鮮有對外的接口和文檔,使得其可操作性不強。不過,如果采用迂回戰術如下圖所示,可以對其進行操作。

 教你如何用AST語法樹對代碼“動手腳”

個推log-rewrite項目改寫日志,就是用AST語法樹進行的,流程圖如下圖所示。

 教你如何用AST語法樹對代碼“動手腳”

先把所有源碼解析為AST語法樹,遍歷每一個編譯單元與單元的類聲明,在類聲明里根據日志方法的簽名找到所有的方法調用,然后遍歷每個方法調用,將方法調用的第二個參數表達式放入遞歸方法,對字符串字面值進行改寫。

 

對應的代碼較為簡短, 使用github的 Netflix-Skunkworks/rewrite開源庫與kotlin語言,能讀懂Java的你也一定能讀明白。

 教你如何用AST語法樹對代碼“動手腳”

如果想將日志恢復原樣,可根據前綴、后綴定制正則表達式,逐行匹配替換。如下圖所示。

 教你如何用AST語法樹對代碼“動手腳”

AST有哪些應用場景?


1、 編譯工具從ant到gradle的切換

 教你如何用AST語法樹對代碼“動手腳”

此項目起步于ant主流時期,隨著技術日漸成熟,gradle逐漸取代了ant的位置,演變成官方的編譯打包方式。因為歷史原因,若直接將上圖類似預編譯的代碼切換到gradle較為棘手,通過AST語法樹重寫,再用gradle編譯,就可以解決此問題。

 教你如何用AST語法樹對代碼“動手腳”


 教你如何用AST語法樹對代碼“動手腳”

上圖的#debug和#mdebug指令,也可以通過AST改寫之后再進行編譯。


2、 自動靜態埋點

 教你如何用AST語法樹對代碼“動手腳”

代碼中需要運營統計、數據分析等,需要通過代碼埋點進行用戶行為數據收集。傳統的做法是手動在代碼中添加埋點代碼,但此過程較為繁瑣,可能會對業務代碼造成干擾,倘若通過改寫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


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

左权县| 岐山县| 天等县| 和平区| 湛江市| 卢湾区| 九龙城区| 高清| 仪陇县| 大田县| 班玛县| 象州县| 文成县| 忻州市| 延寿县| 汉中市| 保德县| 靖宇县| 来宾市| 类乌齐县| 淄博市| 临武县| 和硕县| 吉水县| 阳江市| 迁安市| 溧水县| 临颍县| 鹤峰县| 越西县| 鄂温| 白朗县| 东方市| 刚察县| 嘉禾县| 黎平县| 瑞昌市| 沁源县| 宝丰县| 浪卡子县| 禄劝|