我遇到了一个文本模式匹配的问题,需要一些指导。由于对模式识别整体不太熟悉,我不知道这是不是一个“哦,只需使用某某算法”的问题,还是一个非常难的模式问题。
我想要做的事情的一般陈述是识别一系列SQL语句之间的相似性,以便让我能够将这些语句重构为更少数量的存储过程或其他动态生成的SQL片段。例如,
SELECT MIN(foo) FROM bar WHERE baz > 123;SELECT MIN(footer) FROM bar;SELECT MIN(foo), baz FROM bar;
这些语句在某种程度上是相似的,但我希望能够识别到MIN()内的值应该是可替换的值,我可能在SELECT列表中还有另一列,或者有一个可选的WHERE子句。请注意,这个例子是高度编造的,但我希望它能让你明白我的目标。
就范围而言,我会有一组数千个SQL语句,我希望将其减少到几十个(?)通用语句。在目前的研究中,我遇到了w-shingles和n-grams,并放弃了像“词袋”这样的方法,因为顺序很重要。将这个问题从SQL领域中提出来,另一种表述方式可能是“给定一系列文本语句,可以重新组装这些语句的最小文本片段集是什么?”
回答:
你真正想要的是在代码库中找到代码克隆
。
有很多方法可以做到这一点,但大多数方法似乎忽略了(SQL)语言带来的结构。这种结构使得找到概念上合理的代码元素变得“更容易”,而不是说N-grams(是的,“FROM x WHERE”是常见的,但这是一个尴尬的SQL块)。
我基于抽象语法树(AST)的克隆检测方案将源文本解析为AST,然后找到可以参数化的共享树,通过使用语言语法作为指导,产生合理的概括。请参阅我的技术论文使用抽象语法树进行克隆检测。
关于原帖者的例子:
- 它将识别到MIN()内的值应该是可替换的值
- SELECT单列可以扩展为列表
- WHERE子句是可选的
除非它找到两个候选克隆在这些概括解释的方式上有所不同,否则它不会尝试提出这些建议。它基本上是通过从(SQL)语法中提取这些概括来获得的。原帖者的例子恰好有足够的变化来强制这些概括。
一项关于克隆检测技术的调查(代码克隆检测技术和工具的比较与评估:定性方法)将这种方法评为30种不同的克隆检测方法中的最高;见表14。