【问题标题】:How can I keep track of original character positions in a string across transformations?如何跨转换跟踪字符串中的原始字符位置?
【发布时间】:2011-01-09 00:08:12
【问题描述】:

我正在为我的 CS 课程制定一个反抄袭项目。这涉及通过"Winnowing: Local Algorithms for Document Fingerprinting." 描述的技术检测计算机科学课程(编程作业)中的抄袭行为。

基本上,我要完成一组编程作业。假设其中一项作业如下所示:

public class MyClass
{
    public static void main(String[] args)
    {
        // declare a variable called someVar
        int someVar = 0;
    }
}

这需要通过前端的词法分析部分来去除我们不想要的代码功能。在这种情况下,我想将所有 Identifier names 重命名为常量“V”并从代码中删除所有 cmets

为此,我们将使用ANTLR 和各种语言的现有语法来生成适当的词法分析器。

最终结果是这样的:

public class V
{
    public static void V(String[] V)
    {
        int V = 0;
    }
}

然后我们去掉所有空格得到:

publicclassV{publicstaticvoidV(String[]V){intV=0;}}

这个字符串然后被分解成预设大小的 k-gram。例如说 k = 5(实际上它会更大):

publi ublic blicc liccl iccla ... =0;}}

问题来了:

每个 k-gram 都使用滚动散列函数进行散列,并且应该在源文本中记录它们的原始字符位置。 k-gram 哈希和字符位置一起形成指纹。

如何在标识符、cmets 和空白的所有前端剥离中跟踪源文本中的 k-gram 原始位置?

这对于程序的最后阶段非常重要,您可以在原始源文本中突出显示成对文档中的匹配项。为了突出 k-gram 哈希的匹配,我需要知道 k-gram 在原始源中的开始和结束位置。

【问题讨论】:

标签: java parsing string antlr lexer


【解决方案1】:

嘿,为什么要使用这一步:

这个字符串然后被分解成预设大小的 k-gram。例如说 k = 5(实际上它会更大): publi ublic blicc liccl iccla ... =0;}}

我的意思是为什么抄袭检测需要这样做?

【讨论】:

  • 阅读我上面给出的 PDF 链接。基本上,通过将源代码拆分为 k-gram 并对它们进行散列处理,您可以检测文档之间的匹配,尽管有重新排序和空白。
【解决方案2】:

ANTLR 词法分析器跟踪源流中的标记位置。

  • 将 cmets 和空格移至隐藏通道
  • 将标识符标记的Text 属性设置为“V”
  • 针对CommonTokenStream 运行滚动哈希,查看每个令牌的Text 属性。

在令牌从头到尾完好无损的情况下,您也将保留映射。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-06
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    • 2018-01-23
    • 1970-01-01
    相关资源
    最近更新 更多