当前位置:  开发笔记 > 编程语言 > 正文

从片段中检测编程语言

如何解决《从片段中检测编程语言》经验,为你挑选了6个好方法。

在一段代码中检测使用哪种编程语言的最佳方法是什么?



1> Jules..:

我认为垃圾邮件过滤器中使用的方法可以很好地工作.您将片段拆分为单词.那么你应该比较这些词与已知的片段中的出现次数,并计算这个片段是用语言X为你感兴趣的每一种语言的可能性.

http://en.wikipedia.org/wiki/Bayesian_spam_filtering

如果您有基本机制,那么添加新语言非常容易:只需使用新语言的一些片段训练检测器(您可以将其作为开源项目提供).通过这种方式,它了解到"系统"可能会出现在C#片段中,并且"放入"Ruby片段中.

我实际上已经使用这种方法将语言检测添加到论坛软件的代码片段中.除了模棱两可的情况外,它在100%的时间内都有效:

print "Hello"

让我找到代码.

我找不到代码所以我做了一个新代码.它有点简单,但它适用于我的测试.目前,如果你提供比Ruby代码更多的Python代码,它可能会说这段代码:

def foo
   puts "hi"
end

是Python代码(尽管它确实是Ruby).这是因为Python也有一个def关键字.因此,如果它已经def在Python 中看到了1000x 而def在Ruby中看到了100x ,那么它可能仍然会说Python,尽管putsend是特定于Ruby的.您可以通过跟踪每种语言所看到的单词并将其除以某处(或通过在每种语言中提供相同数量的代码)来解决此问题.

我希望它可以帮助你:

class Classifier
  def initialize
    @data = {}
    @totals = Hash.new(1)
  end

  def words(code)
    code.split(/[^a-z]/).reject{|w| w.empty?}
  end

  def train(code,lang)
    @totals[lang] += 1
    @data[lang] ||= Hash.new(1)
    words(code).each {|w| @data[lang][w] += 1 }
  end

  def classify(code)
    ws = words(code)
    @data.keys.max_by do |lang|
      # We really want to multiply here but I use logs 
      # to avoid floating point underflow
      # (adding logs is equivalent to multiplication)
      Math.log(@totals[lang]) +
      ws.map{|w| Math.log(@data[lang][w])}.reduce(:+)
    end
  end
end

# Example usage

c = Classifier.new

# Train from files
c.train(open("code.rb").read, :ruby)
c.train(open("code.py").read, :python)
c.train(open("code.cs").read, :csharp)

# Test it on another file
c.classify(open("code2.py").read) # => :python (hopefully)


我在我的NLP课上做了类似的事情,但我们更进了一步.你不喜欢看*单*单词的频率,而是单词和三倍的单词.例如,"public"可能是许多语言中的关键字,但"public static void"对于C#来说更为常见.如果找不到三元组,则回落到2,然后是1.
是的.一种避免分裂的方法是使用ngrams:你需要每n个子字符串.例如,5克的"put foo"是"put""uts f","ts fo"和"s foo".这个策略可能看起来很奇怪,但它比你想象的要好,而不是人类如何解决这个问题.要确定哪种方法更好,你必须测试两种方法......
但是,有些语言的语法很少.我还推测常见的变量名称将主导语言的关键字.基本上,如果您的匈牙利语中有一段C代码,其中包含匈牙利语中的变量名称和注释,则在您的训练数据中,其中任何其他匈牙利语源可能会被确定为"相似".

2> nisc..:

语言检测由他人解决:

Ohloh的方法:https://github.com/blackducksw/ohcount/

Github的方法:https://github.com/github/linguist


Github的方法现在也包括贝叶斯分类器.它主要根据文件扩展名检测语言候选,但是当文件扩展名与多个候选项匹配时(例如".h" - > C,C++,ObjC),它会对输入的代码示例进行标记,并根据预先训练的集合进行分类.数据的.可以强制Github版本扫描代码而不查看扩展名.
我检查了这两种解决方案,但都没有完全按照要求进行.他们主要查看文件扩展名以确定语言,因此他们无法在没有扩展线索的情况下检查代码段.

3> Steve..:

您可以在这里找到一些有用的资料:http://alexgorbatchev.com/wiki/SyntaxHighlighter.Alex花了很多时间来弄清楚如何解析大量不同的语言,以及关键的语法元素是什么.


链接已经死了.它似乎搬到了这里:http://alexgorbatchev.com/SyntaxHighlighter/

4> ElectricWarr..:

Guesslang是一个可能的解决方案:

http://guesslang.readthedocs.io/en/latest/index.html

还有SourceClassifier:

https://github.com/chrislo/sourceclassifier/tree/master

在博客文章中找到一些我无法识别的代码后,我对这个问题产生了兴趣.添加此答案,因为这个问题是"识别编程语言"的第一次搜索.



5> 小智..:

这很难,有时甚至是不可能的.这个简短的片段是哪种语言的?

int i = 5;
int k = 0;
for (int j = 100 ; j > i ; i++) {
    j = j + 1000 / i;
    k = k + i * j;
}

(提示:它可能是几个中的任何一个.)

您可以尝试分析各种语言,并尝试使用关键字的频率分析来决定.如果某些关键字在文本中以某些频率出现,那么该语言很可能是Java等.但我认为你不会得到任何完全傻瓜证明的东西,因为你可以命名为例如同名C中的变量作为Java中的关键字,频率分析将被愚弄.

如果你把它提高到一个复杂程度,你可以寻找结构,如果某个关键字总是在另一个关键字之后,那将为你提供更多线索.但是设计和实施起来也会困难得多.


好吧,如果可以使用多种语言,探测器可以提供所有可能的候选者.

6> Andy Jackson..:

另一种方法是使用highlight.js,它执行语法突出显示,但使用突出显示过程的成功率来识别语言.原则上,任何语法高亮显示器代码库都可以以相同的方式使用,但highlight.js的优点是语言检测被认为是一个功能并用于测试目的.

更新:我试过这个并没有那么好用.压缩的JavaScript完全混淆了它,即标记化器对空白敏感.一般来说,只计算高亮点击似乎不太可靠.更强大的解析器,或者可能无法匹配的节数,可能会更好.

推荐阅读
凹凸曼00威威_694
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有