A Slower Speed of Light

Token-词法分析-scanner

  • Textual:代码片段以文本/字符串/词法的形式相互比较,并且只有在两个代码片段在文本内容方面确实相同时才被发现被克隆。

  • Token:在编译器的词法分析阶段,所有源代码行都被划分为一系列Token。 然后将所有Token转换回Token序列。

    词法分析

    词法分析,也称之为扫描(scanner),简单来说就是调用 next() 方法,一个一个字母的来读取字符,然后与定义好的 JavaScript 关键字符做比较,生成对应的Token。Token 是一个不可分割的最小单元:

    例如 var 这三个字符,它只能作为一个整体,语义上不能再被分解,因此它是一个 Token。

    词法分析器里,每个关键字是一个 Token ,每个标识符是一个 Token,每个操作符是一个 Token,每个标点符号也都是一个 Token。除此之外,还会过滤掉源程序中的注释和空白字符(换行符、空格、制表符等。

    最终,整个代码将被分割进一个tokens列表(或者说一维数组)。通过比较一维数组来发现相似代码。

    基于词汇的检测技术也叫基于符号(token)的检测技术,这种技术利用了解析器将源代码分成符号序
    列,然后这些符号序列会被组织成符号的语句,最后将这些符号组成的语句进行比较。

    基于词汇的方法利用
    了更符合编译原理的符号序列,对源代码信息有了更进一步的利用,所以被划分到了比单纯的基于文本的更
    深入的层次。

    相对于基于文本的代码表征方式来说,基于词汇的代码表征方式能够匹配到许多代码特有的信息。但是
    从本质上说,基于词汇的代码表征方式和文本一样都是序列化的表征方法,只是对源代码的利用程度有所提
    升,它有如下几个缺点:

    • (1) 基于词汇的代码表征方式没有考虑到代码行的顺序,如果代码克隆的顺序被改变了,代码克隆将不
      会被检测到。

    • (2) 基于词汇的代码表征方式对于增加删改了符号的代码语句比较敏感,容易漏检特定细微差别的代码
      克隆。

    • (3) 基于词汇的代码表征方式依然没有充分利用源代码的信息,比如它会忽略掉源代码中的结构信息。

  • Syntactic(句法分析):

    • 基于树: 提取的AST用于子树比较以识别相似区域。
    • 基于度量:通过源代码收集度量,然后使用这些度量为每个代码片段生成向量。然后使用向量对代码的相似度进行对比。
  • Semantic:主要检测代码片段不同,但功能相同的函数(Type4)

  • Learning : 通过机器学习和统计分析的方式来进行克隆检测

AST介绍https://juejin.cn/post/6844904035271573511