2012-02-02 49 views
0

目前我在一個源代碼plagiarims檢測項目,我實際上使用輸入文件(源代碼文件)屬性的不同方面來檢測學生作業中的剽竊。例如,我現在使用(標識符/變量的數量,使用的方法數量,代碼行數)以及其他一些屬性來表示每個源代碼文件。Java源代碼屬性計數檢測

但是,當我嘗試計算使用的變量數時,一個問題是如何確定變量是否已被使用。因爲學生可以故意放置一些標識符來掩蓋剽竊。然而,當我試圖解決這個問題時,我發現這真的很難。做到這一點的一種方法是在java中使用正則表達式來處理查找標識符,但找到它們後,我堅持如何檢查使用情況。 (更重要的是,在此之後,我仍然需要找出是否調用java方法。)因此編寫我自己的正則表達式版本可能非常複雜。

我知道在一些像NetBeans一樣的IDE中編輯器可以立即發現變量是否被使用並且強調它。所以我想知道是否有任何檢查使用或不使用變量的好方法。

關於如何檢查變量的任何建議都會很好!

想到的
+0

我的教授的確建議我編寫自己的正則表達式或'編譯器'版本太幼稚了,並告訴我看一些「編譯器編譯器」,但是在我搜索了一下之後,發現了lex和yacc。沒有太多關於編譯器設計的知識,經過一番閱讀後我就迷失了。 – Alex 2012-02-02 07:23:58

回答

1

做這種代碼的分析,你絕對要看看解析器/編譯工具。您無法通過搜索其名稱來確定是否使用變量;您還必須搜索正確的上下文。

我建議看看ANTLR,這是一個基於Java的語言解析工具。它有一個解析Java語法的定義here。不要指望爲您的問題找到一個簡單的解決方案,可以在幾個小時內實施。

另一個基於Java的工具是JavaCC。如果您正在尋找示例代碼來展示如何使用這些工具,請參閱PMD,該代碼使用使用JavaCC構建的解析器來分析Java代碼。

另一種可能性是爲支持代碼分析的IDE編寫插件 - 您可能會有一個更簡單的接口來訪問代碼結構,正如您所說,許多功能已經可用,並且可以簡單地由您的插件調用。

是的,你可能也有一些正則表達式破解你的方式。你是否想要這樣做取決於你想要你的工具的確切程度。在不分析源代碼的情況下,判斷一個變量名的出現是否實際上是該變量的用法僅僅是一種啓發式的猜測。

1

的第一件事是做一些像這樣:

(\w+)\s+<?varname>(\w+)\s*(=[\w\s\(\,)]+)?;

這應該與變量創建像這樣:

int x = 1; 
double y; 
Foo foo = new Foo(); 
Foo foo = new Foo(a,b,c); 

爲了使事情變得不那麼複雜,它可能是一個好主意,以取代;\n之間不在引號之間的所有;。這應該確保你每行有一條語句。

提供的正則表達式除了嘗試匹配變量創建之外,還將變量的名稱放在一個名爲varname的組中,您可以通過matcher這樣的對象訪問該組:String varName = matcher.group("varname");。要查看是否正在使用一個變量就可以檢查,看是否該變量是在等號的右邊,就像這樣:

[^=]+\s*=\s*.*?x.*;

這應該與字符串,例如int y = x;Foo foo = x + y;

然而,一個變量也可以作爲方法的參數,所以你可以做一些事情,像這樣:

.*?\(.*?x.*?\).*?;

這將MATC^h字符串像這樣: foo(x);foo(a,b,c,x);Foo foo = new Foo(a,v,x,y).createNewFoo();Foo foo = new Foo(a,v,x,y).SOMECONSTANT;

應當注意的是,在所提供的正則表達式,x只是這應該與您將能夠提取通過實際的變量名被替換的樣本變量名使用第一個正則表達式。

您可能想看看this正則表達式教程Oracle。

0

IDE將變量的發生分爲兩類:分配給特定變量和簡單用法。使用正則表達式應該很容易識別任務。所有其他的出現應該在代碼中使用該變量。