スニペットがどのプログラミング言語であるかを検出する


23

あなたの課題は、入力としていくつかのソースコードを受け取り、それが記述されているプログラミング言語を出力することです。

たとえば、あなたは入力を持つことができます

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

そして出力

Java

主な2つの目標は、多様性(検出できるプログラミング言語の数)と精度(これらの言語の検出能力)です。

ポリグロット(複数の言語で有効なプログラム)の場合、何をするかを決定できます。プログラムがより可能性が高いと考える言語を出力するか、エラーを出力するか、可能な選択肢の配列を出力することができます(おそらくエラーよりも多くの賛成票を得るでしょう!)。

別の客観的な勝利基準を指定することは非常に難しいため、これはです。投票者は、検出できる言語の数と正確さについて投票してください。


それは不可能です、原因print("")は多くの言語で使用できます。
イスマエルミゲル14

1
編集を行うと、より可能性が高くなります。
イスマエルミゲル14

4
すべての入力に有効な言語はどうですか?空白のような。この文は有効な空白プログラムです。このページ全体が有効な空白プログラムです。
イスマエルミゲル14

1
入力は有効なプログラムであることが保証されていますか?一部の入力class A{public static void main(String[]a){System.println.out("Hello, World!");}}が無効である可能性があります。
ゴーランタンドン14

1
または同様に、HTML入力は常にで始まり、<!DOCTYPE html>その後に<html><body>およびその他のタグ(などmeta)が正しい順序で続きますか?
ゴーランタンドン14

回答:


18

234のテキスト形式-Unixシェル

(すべての言語ではありません-注意深くカウントする必要があります)

file $1

このいくぶんスマートな回答を投稿することをheしますが、それを禁止するルールには何も見られませんfile。例えば:

$ 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シェル
不明、0:警告:通常のマジックファイル `/ etc / magic 'を使用
強度= 280:シェルアーカイブテキスト[application / octet-stream]
強度= 250:Tenex Cシェルスクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 250:Bourne-Againシェルスクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 240:ポールファルスタッドのzshスクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 240:Neil Brownの灰スクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 230:Neil Brownのaeスクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 210:Tenex Cシェルスクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 210:Bourne-Againシェルスクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 190:Tenex Cシェルスクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 190:Bourne-Againシェルスクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 180:Paul Falstadのzshスクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 150:Tenex Cシェルスクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 150:Bourne-Againシェルスクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 140:Cシェルスクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 140:Kornシェルスクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 140:ポールファルスタッドのzshスクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 130:POSIXシェルスクリプトテキスト実行可能ファイル[text / x-shellscript]
強度= 130:プラン9 rcシェルスクリプトテキスト実行可能ファイル[]
$ 

これはfile-5.09(Ubuntu 12.04で)


-これは実際には、16の言語ポリグロットにかなりよくないgist.github.com/riking/9088817
Riking

中間者を切り取り、シェルを完全に回避することもできますln -s /usr/bin/file /usr/local/bin/myspecialtool。あなたの答えがカウントされる場合、これも同様にカウントされませんか?(心配しないでください、私は深刻ではありません。)
hvd 14

2
標準的な抜け穴のように見えます。つまり、既存のプログラムにソリューションを委任します。
Vi。

10

Bash —について 50 コンパイル可能な言語ごとに35バイト

秘isはコンパイルすることです。そうすれば、欠落しているライブラリからのリンクエラーを心配する必要はありません。コードスニペットがあれば、より寛容になります。

短いフォームの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

ありがとう、私は本当にコードを絞るのが苦手です!

確かに。&&そして||bashでは、コードたくさん本当に役に立つとヘルプのクリーンアップにしています。これらは難読化に使用されるものではないため、学習することをお勧めします。
シャーバズ

2
-fsyntax-only構文のみをチェックして、実際のコンパイルをスキップすることもできます。
ペッペ14

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を使用したことがないため、何か間違ったことをしている可能性があります。
マリヌス14

@marinusコードを手動で入力する場合、実行をトリガーするにはEOF(STRG + D)を送信する必要があることに注意してください。一般に、検出器は少なくとも3つの疑問符を吐き出します。
ティムウォラ14

いや、何もない。coffee引数を渡す必要がありますか?ファイルをリダイレクトしてみましたが、実行して実行し^Dても何もしません。
マリヌス14

@marinus Try:npm install coffee-script && node_modules/.bin/coffee timwolla.coffee < timwolla.coffee一時フォルダーに、これが吐き出されるはずAPLです。(ノードとnpmの最新バージョンがインストールされていると仮定)
TimWolla 14

5
APL以外のプログラムでは、小文字のオメガをさらに使い始めます。
ジョンドヴォルザーク14

4

この答えは概念実証であり、私からはこれ以上の仕事を受けることはないでしょう。

いくつかの点で不十分です。

  • 出力は質問のとおりではありませんが、十分に近いため、必要な正確な出力を生成するために簡単に変更できます。
  • コードのパフォーマンスを向上させる方法や、データ構造を表現する方法を改善する方法がいくつかあります。
  • もっと

アイデアは、特定の言語を識別し、各言語のキーワードにスコアを割り当てることができるキーワード/文字/フレーズのリストを設定することです。次に、これらのキーワードのソースファイルを確認し、キーワードが見つかった各言語のスコアを集計します。最終的には、最高得点の言語が勝者になる可能性があります。関連する言語の両方(またはすべて)が高得点になるため、これは多言語プログラムにも対応します。

言語を追加する唯一のことは、それらの「署名」を識別し、それらをマッピングに追加することです。

言語ごとに異なるキーワードに異なるスコアを割り当てることもできます。たとえばvolatile、CよりもJavaの方が使用頻度が高いと感じる場合は、volatileキーワードのスコアをJavaで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はどうですか?
デジタル外傷14

@DigitalTraumaはい、#includeについては正しいと思います。芸術的な理由で、言語の名前が明示的に記述されているハッシュバンをキャッチするつもりはありません。
ダニエロ14

#includeは、内のコメントでini、ファイルやphp
イスマエルミゲル

1
プロローグはあるがCはないため+1 :)
SztupY 14

1
\$\w+perlの後にPHPを検出するために追加します。また、(\w+)::~\1C ++デストラクタは普通です
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("----------------");
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.