亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

教你如何用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

平塘县| 鄄城县| 玛纳斯县| 江津市| 银川市| 聊城市| 吐鲁番市| 多伦县| 荣昌县| 抚宁县| 铜山县| 开原市| 额尔古纳市| 阿坝县| 马尔康县| 辽宁省| 武鸣县| 伊吾县| 静海县| 栾川县| 天水市| 嵊州市| 肥西县| 项城市| 永新县| 祁东县| 常德市| 延吉市| 中方县| 资兴市| 中阳县| 育儿| 云阳县| 闽清县| 平乡县| 嘉义市| 株洲县| 太谷县| 毕节市| 盐山县| 饶平县|