Java源代码属性计数用于检测

时间:2012-02-02 07:23:44

标签: java regex lexical-analysis

目前我正在使用源代码plagiarims检测项目,我实际上使用输入文件属性的不同方面(源代码文件)来检测学生作业中的抄袭。例如,我现在使用(标识符/变量的数量,使用的方法的数量,代码行数)和一些其他属性来表示每个源代码文件。

但是,当我尝试计算所用变量的数量时,一个问题是如何确定是否使用了变量。因为学生可以故意放入一些标识符来掩盖抄袭。然而,当我试图解决这个问题时,我发现这个问题非常困难。实现此目的的一种方法是在java中使用正则表达式来处理查找标识符,但在找到它们之后,我坚持如何检查是否使用。 (更重要的是,在此之后,我仍然需要查找是否调用了java方法。)因此编写我自己的正则表达式版本可能非常复杂。

我知道在一些像netbeans这样的IDE中编辑器可以立即找出变量是否被使用并加下划线。所以我想知道是否有任何好方法可以检查使用的变量。

关于如何检查变量的任何建议都会很好!

3 个答案:

答案 0 :(得分: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.*?\).*?;

等字符串

但是,变量也可以用作方法参数,因此你可以这样做:

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

需要注意的是,在提供的正则表达式中,{{1}}只是一个示例变量名,应该用实际变量名替换,您可以通过使用第一个正则表达式来提取它

您可能希望查看Oracle的this正则表达式教程。

答案 1 :(得分:1)

要进行这种代码分析,您必须查看解析器/编译器工具。您无法通过搜索其名称来确定是否使用变量;你也必须搜索正确的上下文。

我建议看看ANTLR,这是一个基于Java的语言解析工具。它有一个解析Java语法可用的定义here。不要指望为您的问题找到一个可以在几个小时内实施的简单解决方案。

另一个基于Java的工具是JavaCC。如果您正在寻找显示如何使用这些工具的示例代码,请查看PMD,它使用使用JavaCC构建的解析器来分析Java代码。

另一种可能性是为支持代码分析的IDE编写一个插件 - 你可能有一个更简单的接口来访问代码结构,正如你所说,许多功能已经可用,可以简单地调用通过你的插件。

是的,你可能也会用一些正则表达式破解你的方式。是否要执行此操作取决于您希望工具的准确程度。在不解析源代码的情况下,判断变量名称的出现是否实际上是对该变量的使用仅仅是一种启发式猜测。

答案 2 :(得分:0)

IDE将变量的出现分为两类:特定变量的赋值和它的简单用法。使用正则表达式很容易识别赋值。所有其他出现的应该只是使用该变量的代码。