从开始着手SIM的研究已经将近一个月了,总算功夫不负有心人,好歹在SIM上增加了对python程序的支持。现在回过头来想想,真正需要自己动手去编写的代码还是非常有限的,大多时间都是对HUSTOJ代码不熟悉而消耗了。
在HUSTOJ下,通过judge_client调用SIM以实现判题过程的相似度判别,所有判别的数据库均来源于服务器端每次存储的已AC代码,例如题号1000的AC代码存放在data/1000/ac文件夹下。SIM所判别的结果也可以通过修改judge_client.cc及judged.cc中的debug为1,并重新编译这两个文件,将产生的.exe文件复制到/usr/bin文件夹下,重启judged进程即可。SIM输出的结果保存在/home/judge/run0中的sim文件中。当然,也可以通过修改/fps/core/sim下sim.sh文件代码,将判别结果以不同形式输出至制定位置。
python语言的词法分析,其实还是蛮简单的,只需要重写pythonlang.l文件就可以了。因为在SIM计算形似度规则中保留字要比普通标识符的贡献大,所以第一步就是要修改识别保留字。第二步就是识别注释、空格、换行、制表位等无用信息。python的注释分两种:基于单行的注释通过SingleLineCom("#".*)识别即可;基于段的注释通过重写MultiLineCom
("‘‘‘"(.|\n)*)也可实现。最后将pythonlang.l文件放入相应的sim文件夹下,修改makefile文件,增加python的编译生成sim_py可执行程序,拷贝到/usr/bin下,验证之。在初期的调试下,可以通过命令行来验证,./sim_py -p 1.py 2.py |grep ^1.py|awk ‘{print $4}‘输出判别结果。需要注意的是,hustoj默认只支持5种语言的相似度判别,所以增加新的语言时需要将judge_client.cc程序中的2268行&&lang<5这句话删除。
运行判别的两个程序如下:
文件1:
###################
‘‘‘
ldf:a+b
‘‘‘
import sys
for line in sys.stdin:
b = line.split()
print int(b[0]) + int(b[1])
文件2:
import sys
for line in sys.stdin:
a = line.split()
print int(a[0]) + int(a[1])
结果显示文件1与文件2的相似度为100%。