Подсчет атрибутов исходного кода Java для обнаружения - PullRequest
0 голосов
/ 02 февраля 2012

В настоящее время я работаю над проектом по обнаружению плагиата исходного кода и фактически использую различные аспекты атрибутов входных файлов (файлов исходного кода) для обнаружения плагиата среди студенческих заданий. Например, теперь я использую (количество идентификаторов / переменных, количество используемых методов, количество строк кода) и некоторые другие атрибуты для представления каждого файла исходного кода.

Однако, когда я пытаюсь подсчитать количество используемых переменных, одна проблема состоит в том, как узнать, использовалась ли переменная или нет. Потому что студенты могли намеренно ввести некоторые идентификаторы, чтобы покрыть плагиат. Однако, пытаясь решить эту проблему, я обнаружил, что это действительно сложно. Одним из подходов для этого является использование регулярных выражений в Java для обработки поиска идентификаторов, но после их поиска я остановился на том, как проверять использование или нет. (Более того, после этого мне все еще нужно выяснить, вызывается ли java-метод или нет.) Поэтому написание собственной версии регулярного выражения может быть очень сложным.

Я знаю, что в некоторых средах IDE, таких как netbeans, редактор мог мгновенно выяснить, используется ли переменная или нет, и подчеркнуть ее. Поэтому мне интересно, есть ли хороший способ проверки используемых переменных или нет.

Любые предложения по проверке переменных были бы хорошими!

Ответы [ 3 ]

1 голос
/ 02 февраля 2012

Для такого анализа кода вам обязательно нужно изучить инструменты парсера / компилятора.Вы не можете определить, используется ли переменная путем поиска ее простого имени;Вы также должны искать правильный контекст.

Я предлагаю взглянуть на ANTLR , который является инструментом синтаксического анализа на основе Java.В нем есть определение синтаксического анализа Java, доступное здесь .Не надейтесь найти простое решение для вашей проблемы, которое может быть реализовано за пару часов.

Еще один инструмент на основе Java - JavaCC .Если вы ищете пример кода, показывающего, как можно использовать эти инструменты, взгляните на PMD , который использует синтаксический анализатор, созданный с помощью JavaCC для анализа кода Java.

Другая возможность состоит в том, чтобынапишите плагин для IDE, который поддерживает анализ кода - у вас, вероятно, будет гораздо более простой интерфейс для доступа к структуре кода, и, как вы сказали, множество функций уже доступно и может быть просто вызвано вашим плагином.

Да, вы также можете взломать свой путь с помощью некоторых регулярных выражений.Хотите ли вы сделать это, зависит от того, насколько точным будет ваш инструмент.Без разбора исходного кода решение о том, является ли вхождение имени переменной фактически использованием этой переменной, является просто эвристическим предположением.

1 голос
/ 02 февраля 2012

Первое, что приходит в голову, это сделать что-то вроде этого:

(\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 - это просто пример имени переменной, который должен быть заменен фактическим именем переменной, которое вы сможете извлечь с помощью первого регулярного выражения.

Возможно, вы захотите взглянуть на это руководство по регулярным выражениям Oracle.

0 голосов
/ 02 февраля 2012

Среды IDE классифицируют вхождения переменных на две категории: присваивания определенной переменной и простое ее использование.Назначение должно быть легко распознать с помощью регулярных выражений.Все остальные вхождения должны быть в коде только с использованием этой переменной.

...