2011-05-16 139 views
3

我正在尋找一種方法,使用兩個JavaScript函數的靜態分析來判斷它們是否相同。讓我定義「相同」的多個定義。靜態解析:判斷兩個Javascript函數是否相同

等級1:除了可能的不同空白(例如, TABS,CR,LF和SPACES。

2級函數可能有不同的空白,如1級,但也可能有不同的變量名稱。

3級 ???


對於一個水平,我想我可以只含有兩個JS函數定義每個字符串中刪除所有(非文本,這可能是艱難的)空白,然後比較字符串。

對於二級,我想我需要使用類似SpiderMonkey's parser的東西來生成兩個解析樹,然後編寫一個比較器來遍歷樹並允許變量具有不同的名稱。


[編輯] Williham,使得下面好點。我的意思是相同的。現在,我正在尋找一些實用策略,特別是關於使用分析樹的方面。

+0

對於第一級,您的計劃將無法一直工作。例如,0011與00011「相同」,但空白標準化將不會看到那個;對於所有其他具有相同值的變體「拼寫」也可以是字符,數字或字符串。對於JavaScript,你也擔心「可選」分號。 – 2011-05-16 22:14:46

回答

3

重新編輯:

要在我的建議闡述用於確定相同的功能,下面的流可被提示:

等級1:刪除任何空白不是一個字符串的一部分;在每個{,;}之後插入換行符並進行比較。如果相等;功能是相同的,如果不是:

級別2:移動所有變量聲明和賦值,這些變量聲明和賦值不依賴於在同一範圍內定義的其他變量的狀態到它們聲明的範圍的開始處(或if不想實際解析JS;大括號的開始);並按行長排序;將所有變量名稱視爲長度爲4個字符,並且在長度相同時忽略變量名稱。按字母順序重新排列所有集合,並重命名所有變量vSNN,其中v是文字,S是嵌套花括號的數量,NN是變量遇到的順序。

比較;如果相等,則各功能是相同的,如果不是:

級別3:與"sNN",其中"s是文字全部替換字符串文字,和NN是在其中遇到串的順序。比較;如果不相等,則功能相同:

級別4:根據字母順序使用具有最高優先級的函數的名稱標準化已知的任何函數的名稱(在下面的示例中,到p_strlen()任何呼叫將與c_strlen()代替重複重新排序按如有必要1水平比較;如果相等,則各功能是相同的,如果不是,該功能幾乎肯定是不相同


。原始回答:

我想你會發現你的意思是「相同」,而不是「相同」。

的區別,因爲你會發現,是至關重要的:

兩個功能相同如果按照規範化的某種方式,(除去非字面空格,重命名和重新排序變量標準化秩序,用佔位符替換字符串文字,...)他們比較字面上相等。

兩個函數是相同如果在任何給定的輸入值被調用時它們會給出相同的返回值。在一般情況下,考慮一種編程語言,它計算了零終止字符串(如果您願意的話,可以使用混合Pascal/C字符串)。函數p_strlen(str)可能會查看字符串的字符數並返回該字符。函數c_strlen(str)可能會計算字符串中的字符數並返回該字符數。

雖然這些函數肯定不會相同,但它們將是相同的:對於任何給定的(有效)輸入值,它們將給出相同的值。


我的觀點是:

確定閹兩個功能是相同的(你似乎想達到什麼)是(中等)很重要的問題,做你描述。

確定這兩個函數是否真的是一樣的(你可能想要實現的)是不平凡的;事實上,它很難完成,可能與Halting Problem有關,而不是靜態分析可以做到的。


編輯:當然,這是相同的功能也相同;但以完全分析的高度特異且很少有用的方式。

1

您的級別1的方法似乎是合理的。

對於2級,如何對每個函數做一些基本的變量替換,然後確定是否達到1級?從開始處開始,對於每個遇到的變量聲明,將它們重命名爲var1, var2, ... varX

如果函數聲明變量的順序不同,則這沒有幫助... var ivar j可能在這兩個函數中都以相同的方式使用,但是以不同的順序聲明。然後你可能會像你提到的那樣對樹分析進行比較。

1

查看我公司的(語義設計)Smart Differencer工具。這個工具家族根據感興趣的語言(在你的情況下,JavaScript)的編譯器級別細節語法解析源代碼,構建AST,然後比較AST(它們有效地忽略了空白和註釋)。字面值被標準化,所以它們如何「拼寫」並不重要; 10E17具有與1E18相同的標準化值。

如果兩棵樹相同,它會告訴你「沒有區別」。如果它們通過標識符的一致重命名而不同,則該工具將告訴您consisten重命名以及它發生的塊。其他差異以語言元素(標識符,語句,塊,類,...)插入,刪除,複製或移動來報告。目標是報告可以解釋差異的一小組三角形。您可以在網站上查看許多語言的示例。

你不能在實踐中超出這個範圍;以確定兩個函數是否計算相同的答案,原則上你必須解決暫停問題。您可能能夠檢測出作爲交換列表元素的兩種語言元素可以在沒有影響的情況下進行減法;我們正在研究這個。您可能能夠應用規範化重寫來規範化某些形式(例如,將所有多個聲明映射到詞法排序的單個聲明序列中)。您可能能夠將源代碼轉換爲其等價的數據流集,並進行圖同構匹配(麻省理工學院的程序員學徒提出要做到這一點,但我不認爲他們曾經到過那裏)。

所有有更多的工作要做,比你想象的要多。

相關問題