检测代码段是什么编程语言


23

您面临的挑战是将一些源代码作为输入,并输出用哪种编程语言编写。

例如,您可以输入

class A{public static void main(String[]a){System.out.println("Hello, World!");}}

并输出

Java

您的两个主要目标是多样性(可以检测多少种编程语言)和准确性(在检测这些语言方面有多强)。

对于多语种(程序以一种以上的语言有效),您可以决定要做什么。您可以只输出程序认为更可能的语言,也可以输出错误,或者输出一系列可能的选择(可能会得到更多的支持,而不仅仅是错误!)。

这是一场,因为很难指定其他客观的获胜标准。选民,请投票选出它可以检测到多少种语言以及它有多准确。


这是不可能的,原因print("")可以用于多种语言。
伊斯梅尔·米格尔

1
通过您的编辑,现在似乎更有可能。
Ismael Miguel

4
对于每种输入都有效的语言呢?像空白。这句话是有效的空白程序。这整个页面是有效的空白程序。
Ismael Miguel 2014年

1
输入是否保证是有效程序?像某些输入可能class A{public static void main(String[]a){System.println.out("Hello, World!");}}是无效的。
Gaurang Tandon 2014年

1
或同样地将HTML输入总是先从<!DOCTYPE html>其次<html><body>和其他标签(比如meta在正确的顺序)?
Gaurang Tandon 2014年

Answers:


18

234种文本格式-Unix Shell

(不是所有的语言-我需要仔细计数)

file $1

我毫不犹豫地发布了这个有点聪明的答案,但是我在禁止它的规则中看不到任何东西,fileshell实用程序确实做到了这一点。例如:

$ file golfscript.rb 
golfscript.rb: Ruby module source, ASCII text
$ file template.c 
template.c: ASCII C program text
$ file adams.sh
adams.sh: Bourne-Again shell script, ASCII text executable
$ 

此外,-k在测试多语种时,您可以使用选项“继续进行”:

 -k, --keep-going
         Don't stop at the first match, keep going.  Subsequent matches
         will be have the string ‘\012- ’ prepended.  (If you want a new‐
         line, see the -r option.)

此外,该-l选项还将使您了解该算法对于不同语言的性能如何:

$ file -l | grep shell
未知,0:警告:使用常规魔术文件`/ etc / magic'
强度= 280:shell存档文本[application / octet-stream]
强度= 250:Tenex C Shell脚本文本可执行文件[text / x-shellscript]
强度= 250:Bourne-Again Shell脚本文本可执行文件[text / x-shellscript]
强度= 240:Paul Falstad的zsh脚本文本可执行文件[text / x-shellscript]
强度= 240:尼尔·布朗的灰脚本文字可执行文件[text / x-shellscript]
强度= 230:尼尔·布朗的ae脚本文本可执行文件[text / x-shellscript]
强度= 210:Tenex C Shell脚本文本可执行文件[text / x-shellscript]
强度= 210:Bourne-Again Shell脚本文本可执行文件[text / x-shellscript]
强度= 190:Tenex C Shell脚本文本可执行文件[text / x-shellscript]
强度= 190:Bourne-Again Shell脚本文本可执行文件[text / x-shellscript]
强度= 180:Paul Falstad的zsh脚本文本可执行文件[text / x-shellscript]
强度= 150:Tenex C Shell脚本文本可执行文件[text / x-shellscript]
强度= 150:Bourne-Again Shell脚本文本可执行文件[text / x-shellscript]
强度= 140:C Shell脚本文本可执行文件[text / x-shellscript]
强度= 140:Korn Shell脚本文本可执行文件[text / x-shellscript]
强度= 140:Paul Falstad的zsh脚本文本可执行文件[text / x-shellscript]
强度= 130:POSIX Shell脚本文本可执行文件[text / x-shellscript]
强度= 130:计划9 rc shell脚本文本可执行文件[]
$ 

这是file-5.09(在Ubuntu 12.04上)


实际上,这在16种语言的多语言版本上效果很好-gist.github.com/riking/9088817
Riking

您最好切掉中间人并完全避免使用炮弹:ln -s /usr/bin/file /usr/local/bin/myspecialtool。如果您的答案很重要,那么这还不算很重要吗?(不用担心,我并不认真。)
2014年

2
看起来像一个标准漏洞,即委派现有程序的解决方案。
六。

10

重击-关于 50 每种可编译语言35个字节

技巧就是编译,那么您不必担心从缺少的库中链接错误,如果您仅拥有代码片段,则可以更宽容。

感谢Shahbaz提供的简短表格!

gcc -c $1 && (echo C; exit 0)
g++ -c $1 && (echo C++; exit 0)
gpc -c $1 && (echo Pascal; exit 0)
gfortran -c $1 && (echo Fortran; exit 0)

等等...


由于您提到了每种可编译语言的字节数,因此您可能会对以下代码行感兴趣:gcc -c $1 && (echo C; exit 0)
Shahbaz 2014年

谢谢,我不太擅长压缩代码!

当然。bash中的&&||非常有用,可以帮助清理大量代码。它们绝不用于混淆,因此您最好学习它们。
Shahbaz 2014年

2
您还可以通过-fsyntax-only以仅检查语法并跳过实际编译。
peppe 2014年

7

18种编程语言,1002字节,准确性:自己测试:)

(是的,我知道这不是代码高尔夫球,而是为了乐趣)

程序搜索标志性代码段,以最清晰的检查在顶部的方式对检查进行排序,而嵌入其他编程语言的编程语言在下面(例如PHP中的HTML)进行排序。

对于诸如 System.out.println('<?php');

t = (p) ->
    h = (x) -> -1 != p.indexOf x
    s = (x) -> 0 == p.indexOf x

    if h "⍵" then "APL"
    else if h "<?php" then "PHP"
    else if h("<?xml") and h "<html" then "XHTML"
    else if h "<html" then "HTML"
    else if h "<?xml" then "XML"
    else if h("jQuery") or h "document.get" then "JavaScript"
    else if h "def __init__(self" then "Python"
    else if h "\\documentclass" then "TeX"
    else if h("java.") or h "public class" then "Java"
    else if s("SELE") or s("UPDATE") or s "DELE" then "SQL"
    else if /[-\+\.,\[\]\>\<]{9}/.test p then "Brainfuck"
    else if h "NSString" then "Objective-C"
    else if h "do |" then "Ruby"
    else if h("prototype") or h "$(" then "JavaScript"
    else if h "(defun" then "Common Lisp"
    else if /::\s*[a-z]+\s*->/i.test p then "Haskell"
    else if h "using System" then "C#"
    else if h "#include"
        if h("iostream") or h "using namespace" then "C++"
        else "C"
    else "???"

program = ""
process.stdin.on 'data', (chunk) -> program += chunk
process.stdin.on 'end', -> console.log t program

节点上的用法: coffee timwolla.coffee < Example.java

演示(JSFiddle上的在线演示):

[timwolla@~/workspace/js]coffee puzzle.coffee < ../c/nginx/src/core/nginx.c 
C
[timwolla@~/workspace/js]coffee puzzle.coffee < ../ruby/github-services/lib/service.rb
Ruby
[timwolla@~/workspace/js]coffee puzzle.coffee < ../python/seafile/python/seaserv/api.py
Python

在我的计算机上,这什么也没输出,甚至在显然应该起作用的输入上也没有。当然,我可能做错了,因为我以前从未使用过Coffeescript。
marinus 2014年

@marinus请注意,手动输入代码时,需要发送EOF(STRG + D)来触发执行。通常:检测器至少应吐出三个问号。
TimWolla

不,没有。我需要传递coffee任何论点吗?我刚刚尝试将文件重定向到其中,但是仅运行它并^D不会执行任何操作。
marinus 2014年

@marinus尝试:npm install coffee-script && node_modules/.bin/coffee timwolla.coffee < timwolla.coffee在一个临时文件夹中,应吐出APL。(假设您已安装了最新版本的node和npm)
TimWolla 2014年

5
我将在非APL程序中更多地使用小写的omega。
约翰·德沃夏克

4

这个答案是一个概念证明,不会再让我自己做任何工作。

它在以下几个方面达不到要求:

  • 输出与问题所要求的不完全相同,但足够接近,可以轻松修改以产生所需的确切输出。
  • 有几种方法可以使代码执行得更好,和/或更好的方法可以代表数据结构。
  • 和更多

想法是设置关键字/字符/短语的列表,这些列表可以识别特定语言并为每种语言的关键字分配分数。然后在源文件中检查这些关键字,并为您找到关键字的每种语言计算分数。最后,得分最高的语言可能是赢家。由于两种(或全部)相关语言的得分都很高,因此这也满足了多种语言的计划。

添加更多语言的唯一方法是识别它们的“签名”,并将其添加到映射中。

您还可以为每种语言的不同关键字分配不同的分数。例如,如果您觉得volatile在Java中使用的次数比在C中使用的次数多,则将volatileJava的关键字得分设置为2 ,将C的得分设置为1。

public class SourceTest {

  public static void main(String[] args) {
    if (args.length < 1) {
      System.out.println("No file provided.");
      System.exit(0);
    }
    SourceTest sourceTest = new SourceTest();
    for (String fileName : args) {
      try {
        sourceTest.checkFile(fileName);
      } catch (FileNotFoundException e) {
        System.out.println(fileName + " : not found.");
      } catch (IOException e) {
        System.out.println(fileName + " : could not read");
      }
    }
    System.exit(0);
  }

  private Map<String, LanguagePoints> keyWordPoints;
  private Map<LANGUAGES, Integer> scores;

  private enum LANGUAGES {
    C, HTML, JAVA;
  }

  public SourceTest() {
    init();
  }

  public void checkFile(String fileName) throws FileNotFoundException, IOException {
    String fileContent = getFileContent(fileName);
    testFile(fileContent);
    printResults(fileName);
  }

  private void printResults(String fileName) {
    System.out.println(fileName);
    for (LANGUAGES lang : scores.keySet()) {
      System.out.println("\t" + lang + "\t" + scores.get(lang));
    }
  }

  private void testFile(String fileContent) {
    for (String key : keyWordPoints.keySet()) {
      if (fileContent.indexOf(key) != -1) {
        for (LANGUAGES lang : keyWordPoints.get(key).keySet()) {
          scores.put(lang, scores.get(lang) == null ? new Integer(1) : scores.get(lang) + 1);
        }
      }
    }
  }

  private String getFileContent(String fileName) throws FileNotFoundException, IOException {
    File file = new File(fileName);
    FileReader fr = new FileReader(file);// Using 1.6 so no Files
    BufferedReader br = new BufferedReader(fr);
    StringBuilder fileContent = new StringBuilder();
    String line = br.readLine();
    while (line != null) {
      fileContent.append(line);
      line = br.readLine();
    }
    return fileContent.toString();
  }

  private void init() {
    scores = new HashMap<LANGUAGES, Integer>();

    keyWordPoints = new HashMap<String, LanguagePoints>();
    keyWordPoints.put("public class", new LanguagePoints().add(LANGUAGES.JAVA, 1));
    keyWordPoints.put("public static void main", new LanguagePoints().add(LANGUAGES.JAVA, 1));
    keyWordPoints.put("<html", new LanguagePoints().add(LANGUAGES.HTML, 1));
    keyWordPoints.put("<body", new LanguagePoints().add(LANGUAGES.HTML, 1));
    keyWordPoints.put("cout", new LanguagePoints().add(LANGUAGES.C, 1));
    keyWordPoints.put("#include", new LanguagePoints().add(LANGUAGES.C, 1));
    keyWordPoints.put("volatile", new LanguagePoints().add(LANGUAGES.JAVA, 1).add(LANGUAGES.C, 1));
  }

  private class LanguagePoints extends HashMap<LANGUAGES, Integer> {
    public LanguagePoints add(LANGUAGES l, Integer i) {
      this.put(l, i);
      return this;
    }
  }
}

4

只是一些概括。

我认为这是相当准确的。

这是Ruby Btw。从stdin获取(多行)输入。

puts case $<.read
when /\)\)\)\)\)/
  "Lisp"
when /}\s+}\s+}\s+}/
  "Java"
when /<>/
  "Perl"
when /|\w+|/
  "Ruby"
when /\w+ :- \w+ \./
  "Prolog"
when /^[+-<>\[\],.]+$/
  "brainfuck"
when /\[\[.*\]\]/
  "Bash"
when /~]\.{,/
  "golfscript"
end

我认为#include是c的更好预测指标。bash / shell脚本的#!/ bin /(ba)?sh呢?
Digital Trauma

@DigitalTrauma是的,我认为您对#include是正确的。出于艺术上的原因,我不会仅仅因为语言的名称被明确拼写出来而引起混乱。
daniero 2014年

#include是ini文件中的注释,以及php
Ismael Miguel

1
+1因为有序言,但没有C :)
SztupY

1
我将\$\w+在perl之后添加一个以检测PHP。也(\w+)::~\1通常是一个C ++析构函数
SztupY

2

Javascript-6种语言-高精度

当前语言:Java,C,HTML,PHP,CSS,Javascript

我的工作原理是,只要输入满足标准,就会获得一个分数,并根据该分数给出结果。

特征:

  • 没有确定使用语言类型的内置函数。
  • 不要立即声明输入的文本是x看到关键字时的语言。
  • 还建议其他可能的语言。

如果您觉得程序的任何输入(我到目前为止所做的)没有被捕获或得到了无效的结果,请报告,我很乐意修复它们。

样本输入1:

class A{public static void main(String[]a){System.out.println("<?php");}}

样本输出1:

My program thinks you have :
Java with a chance of 100%
Php with a chance of 25%
----------------

说明:

这本来应该使程序失败PHP,但我会打印出来,但是由于我的程序是基于分数运行的,因此没有任何故障,并且很容易首先识别Java,然后是其他可能的结果。

样本输入2:

class A{public static void main(String[]a){System.out.println("HelloWorld!");}}

样本输出2:

Java
----------------

样本输入3:

ABCDEFGHIJKLMNOPQRSTUVWXYZ

样本输出3:

Language not catched! Sorry.
----------------

代码:

// Helper functions

String.prototype.m = function(condition){
  return this.match(condition);
};

String.prototype.capitalize = function(){
  return this[0].toUpperCase() + this.substr(1);
};

function getFuncName(func){
  var temp =  func.toString();
  temp = temp.substr( "function ".length);
  temp = temp.substr( 0, temp.indexOf("("));
  return temp.capitalize();
}

// Get input
var lang_input = prompt("Enter programming language");

// Max score of 4 per lang

function java(input){
  var score = 0;
  score += input.m(/class[\s\n]+[\w$]+[\s\n]*\{/) ? 1 : 0;
  score += input.m(/public[\s\n]+static[\s\n]+void[\s\n]+main[\s\n]*/) ? 1 : 0;
  score += input.m(/\}[\s\n]*\}[\s\n]*$/) ? 1 : 0;
  score += input.m(/System[\s\n]*[.][\s\n]*out/) ? 1 : 0;
  return score;
}

function c(input){
  var score = 0;
  // if java has passsed
  if(checks[0][1] >= 3)return 0;

  score += input.m(/^#include\s+<[\w.]+>\s*\n/) ? 1 : 0;
  score += input.m(/main[\s\n]*\([\s\n]*(void)?[\s\n]*\)[\s\n]*\{/) ? 1 : 0;
  score += input.m(/printf[\s\n]+\(/) || input.m(/%d/) ? 1 : 0;
  score += input.m(/#include\s+<[\w.]+>\s*\n/) || input.m(/(%c|%f|%s)/) ? 1 : 0;
  return score;
}

function PHP(input){
  var score = 0;
  score += input.m(/<\?php/) ? 1 : 0;
  score += input.m(/\?>/) ? 1 : 0;
  score += input.m(/echo/) ? 1 : 0;
  score += input.m(/$[\w]+\s*=\s*/) ? 1 : 0;
  return score;
}

function HTML(input){
  var score = 0;
  // if php has passed
  if(checks[2][1] >= 2) return 0;

  score += input.m(/<!DOCTYPE ["' \w:\/\/]*>/) ? 1 : 0;
  score += input.m(/<html>/) && input.m(/<\/html>/) ? 1 : 0;
  score += input.m(/<body>/) && input.m(/<\/body/) ? 1 :  0;
  score += input.m(/<head>/) && input.m(/<\/head>/) ? 1 : 0;
  return score;
}

function javascript(input){
  var score = 0;
  score += input.m(/console[\s\n]*[.][\s\n]*log[\s\n*]\(/) ? 1 : 0;
  score += input.m(/[\s\n]*var[\s\n]+/) ? 1 : 0;
  score += input.m(/[\s\n]*function[\s\n]+[\w]+[\s\n]+\(/) ? 1 : 0;
  score += input.m(/document[\s\n]*[.]/) || 
           ( input.m(/\/\*/) && input.m(/\*\//) ) ||
           ( input.m(/\/\/.*\n/) )? 1 : 0;
  return score;
}

function CSS(input){
  var score = 0;
  score += input.m(/[a-zA-Z]+[\s\n]*\{[\w\n]*[a-zA-Z\-]+[\s\n]*:/) ? 1 : 0;
  // since color is more common, I give it a separate place
  score += input.m(/color/) ? 1 : 0;          
  score += input.m(/height/) || input.m(/width/) ? 1 : 0;
  score += input.m(/#[a-zA-Z]+[\s\n]*\{[\w\n]*[a-zA-Z\-]+[\s\n]*:/) ||
           input.m(/[.][a-zA-Z]+[\s\n]*\{[\w\n]*[a-zA-Z\-]+[\s\n]*:/) ||
           ( input.m(/\/\*/) && input.m(/\*\//) ) ? 1 : 0;
  return score;
}

// [Langs to check, scores]
var checks = [[java, 0], [c, 0], [PHP, 0], [HTML, 0], [javascript, 0], [CSS, 0]];
//Their scores

// Assign scores
for(var i = 0; i < checks.length; i++){
  var func = checks[i][0];
  checks[i][1] = func(lang_input);
}

// Sort the scores
checks.sort(function(a,b){ return b[1] - a[1]; });

var all_zero = true;

function check_all_zero(index){
  if(checks[index][1] > 0){ all_zero = false; return 0; } // someone is above zero

  // check next index only if it defined, else return zero
  if(checks[index + 1])
    check_all_zero(index + 1);
}

check_all_zero(0);

if(all_zero){
  console.log("Language not catched! Sorry.");
}else {
  var new_arr = [];                   // temp

  checks.map(function(value, index){
    if(value[1] > 0){
      var temp = [getFuncName(value[0]), value[1]];
      new_arr.push(temp);
    }
  });

  checks = new_arr.slice(0);          // array copy, because of mutation

  if(checks.length === 1){
    console.log(checks[0][0]);
  }else{
    console.log("My program thinks you have :");
    checks.map(function(value){
      var prob = (value[1]/4 * 100);
      console.log(value[0] + " with a chance of " + prob + "%");
    });
  }

} // Main else block finish

console.log("----------------");
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.