Mendeteksi apa bahasa pemrograman cuplikan

23

Tantangan Anda adalah untuk mengambil beberapa kode sumber sebagai input, dan menampilkan bahasa pemrograman tempat penulisan itu.

Misalnya, Anda dapat memiliki input

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

Dan output

Java

Dua tujuan utama Anda adalah keanekaragaman (berapa banyak bahasa pemrograman yang dapat Anda deteksi) dan akurasi (seberapa baik Anda mendeteksi bahasa-bahasa ini).

Untuk polyglots (program yang valid dalam lebih dari satu bahasa), Anda dapat memutuskan apa yang harus dilakukan. Anda hanya bisa menampilkan bahasa yang menurut program Anda lebih mungkin, atau Anda bisa menampilkan kesalahan, atau Anda bisa menampilkan berbagai pilihan yang mungkin (yang mungkin akan mendapatkan lebih banyak upvotes daripada hanya kesalahan!).

Ini adalah , karena akan sangat sulit untuk menentukan kriteria kemenangan objektif yang berbeda. Pemilih, silakan pilih berapa banyak bahasa yang dapat dideteksi dan seberapa akurat itu.

Gagang pintu
sumber
Itu tidak mungkin, sebab print("")bisa digunakan dalam banyak bahasa.
Ismael Miguel
1
Dengan hasil edit Anda, sekarang tampaknya lebih mungkin.
Ismael Miguel
4
Bagaimana dengan bahasa yang valid untuk input SETIAP? Seperti ruang putih. Kalimat ini adalah program spasi putih yang valid. Seluruh halaman ini adalah program spasi putih yang valid.
Ismael Miguel
1
Apakah input dijamin program yang valid? Seperti beberapa input yang mungkin class A{public static void main(String[]a){System.println.out("Hello, World!");}}tidak valid.
Gaurang Tandon
1
Atau juga apakah input HTML akan selalu dimulai dengan <!DOCTYPE html>diikuti oleh <html>, <body>dan tag lain (seperti meta) dalam urutan yang benar?
Gaurang Tandon

Jawaban:

18

234 format teks - Unix Shell

(tidak semuanya bahasa - saya perlu menghitungnya dengan cermat)

file $1

Saya ragu untuk mengirimkan jawaban yang agak pintar ini, tetapi saya tidak melihat ada aturan melarangnya dan fileutilitas shell benar-benar melakukan pekerjaan dengan baik. misalnya:

$ 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
$ 

Selain itu, Anda dapat menggunakan -kopsi untuk "terus" ketika menguji polyglot:

 -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.)

Selain itu, -lopsi ini akan memberi Anda gambaran tentang seberapa baik algoritma untuk berbagai bahasa:

$ file -l | grep shell
tidak diketahui, 0: Peringatan: menggunakan file ajaib biasa `/ etc / magic '
Kekuatan = 280: teks arsip shell [application / octet-stream]
Kekuatan = 250: Teks skrip shell Tenex C dapat dieksekusi [text / x-shellscript]
Kekuatan = 250: Teks skrip Bourne-Again dapat dieksekusi [text / x-shellscript]
Kekuatan = 240: Teks skrip Paul zsh dieksekusi [teks / x-shellscript]
Kekuatan = 240: Teks naskah abu Neil Brown dapat dieksekusi [teks / x-shellscript]
Kekuatan = 230: Teks skrip ae Neil Brown dapat dieksekusi [teks / x-shellscript]
Kekuatan = 210: Teks skrip shell Tenex C dapat dieksekusi [text / x-shellscript]
Kekuatan = 210: Teks skrip Bourne-Again dapat dieksekusi [text / x-shellscript]
Kekuatan = 190: Teks skrip shell Tenex C dapat dieksekusi [text / x-shellscript]
Kekuatan = 190: Teks skrip Bourne-Again dapat dieksekusi [text / x-shellscript]
Kekuatan = 180: Teks skrip zsh Paul Falstad dapat dieksekusi [teks / x-shellscript]
Kekuatan = 150: Teks skrip shell Tenex C dapat dieksekusi [text / x-shellscript]
Kekuatan = 150: Teks skrip Bourne-Again dieksekusi [teks / x-shellscript]
Kekuatan = 140: Teks skrip shell dieksekusi [text / x-shellscript]
Kekuatan = 140: Teks skrip shell Korn dapat dieksekusi [text / x-shellscript]
Kekuatan = 140: Teks skrip zsh Paul Falstad dapat dieksekusi [teks / x-shellscript]
Kekuatan = 130: Teks skrip POSIX dapat dieksekusi [teks / x-shellscript]
Kekuatan = 130: Teks skrip rc shell Plan 9 dapat dieksekusi []
$ 

Ini file-5.09(di Ubuntu 12.04)

Trauma Digital
sumber
Ini sebenarnya cukup baik pada polyglot 16-bahasa - gist.github.com/riking/9088817
Riking
Anda mungkin juga memotong tengah-tengah manusia dan menghindari shell sepenuhnya: ln -s /usr/bin/file /usr/local/bin/myspecialtool. Jika jawaban Anda penting, bukankah ini juga berarti? (Jangan khawatir, saya tidak serius.)
hvd
2
Tampak seperti celah standar, yaitu mendelegasikan solusi untuk program yang ada.
Vi.
10

Bash - tentang 50 35 byte per bahasa yang dapat dikompilasi

Trik adalah dengan hanya mengkompilasi, maka Anda tidak perlu khawatir tentang menghubungkan kesalahan dari pustaka yang hilang, dan itu lebih memaafkan jika Anda hanya memiliki potongan kode.

Terima kasih kepada Shahbaz untuk formulir yang lebih pendek!

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)

dll ...


sumber
Karena Anda menyebutkan jumlah byte per bahasa yang dapat dikompilasi, Anda mungkin tertarik pada baris seperti:gcc -c $1 && (echo C; exit 0)
Shahbaz
Terima kasih, saya tidak pandai benar-benar memeras kode!
Yakin. The &&dan ||di bash benar-benar berguna dan membantu pembersihan kode banyak. Mereka sama sekali tidak digunakan untuk kebingungan, jadi sebaiknya Anda mempelajarinya.
Shahbaz
2
Anda juga dapat meneruskan -fsyntax-onlyuntuk hanya memeriksa sintaks dan melewati kompilasi yang sebenarnya.
peppe
7

18 bahasa pemrograman, 1002 byte, akurasi: tes sendiri :)

(Ya saya tahu ini bukan kode golf, tetapi untuk bersenang-senang)

Program mencari potongan kode ikonik, cek disusun sedemikian rupa sehingga cek paling jelas ada di bagian atas dan bahasa pemrograman yang tertanam dalam bahasa pemrograman lain ada di bawah ini (mis. HTML dalam PHP).

Ini jelas gagal untuk program seperti 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

Penggunaan pada simpul: coffee timwolla.coffee < Example.java

Demo (Demo Online di 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
TimWolla
sumber
Di komputer saya ini tidak menghasilkan apa-apa, bahkan pada input yang jelas harus bekerja. Memang, saya mungkin melakukan sesuatu yang salah karena saya belum pernah menggunakan Coffeescript sebelumnya.
marinus
@marinus Perhatikan bahwa ketika memasukkan kode secara manual, Anda harus mengirim EOF (STRG + D) untuk memicu eksekusi. Secara umum: Detektor setidaknya harus mengeluarkan tiga tanda tanya.
TimWolla
Tidak, tidak ada. Apakah saya perlu menyampaikan coffeeargumen? Saya baru saja mencoba mengarahkan ulang file ke dalamnya, tetapi hanya menjalankannya dan pergi ^Dtidak melakukan apa-apa juga.
marinus
@marinus Coba: npm install coffee-script && node_modules/.bin/coffee timwolla.coffee < timwolla.coffeedalam folder sementara, ini harus dimuntahkan APL. (dengan asumsi Anda memiliki versi terbaru dari node dan npm diinstal)
TimWolla
5
Saya akan mulai menggunakan omega huruf kecil lebih banyak di program non-APL saya.
John Dvorak
4

Jawaban ini adalah bukti konsep, yang kemungkinan besar tidak akan menerima lebih banyak pekerjaan dari saya.

Gagal dalam beberapa cara:

  • Outputnya tidak persis seperti yang diminta pertanyaan, tetapi cukup dekat dan dapat dengan mudah dimodifikasi untuk menghasilkan output tepat yang diperlukan.
  • Ada beberapa cara untuk membuat kode bekerja lebih baik dan / atau cara yang lebih baik untuk mewakili struktur data.
  • dan lainnya

Idenya adalah untuk menetapkan daftar kata kunci / karakter / frasa yang dapat mengidentifikasi bahasa tertentu dan menetapkan skor untuk kata kunci tersebut untuk setiap bahasa. Kemudian periksa file sumber untuk kata kunci ini, dan hitung skor untuk setiap bahasa yang Anda temukan untuk kata kunci. Pada akhirnya bahasa dengan skor tertinggi adalah kemungkinan pemenang. Ini juga melayani program polyglot karena kedua (atau semua) bahasa yang relevan akan mendapat skor tinggi.

Satu-satunya hal untuk menambahkan lebih banyak bahasa adalah mengidentifikasi "tanda tangan" mereka dan menambahkannya ke pemetaan.

Anda juga dapat menetapkan skor berbeda untuk kata kunci berbeda per bahasa. Misalnya, jika Anda merasa volatilelebih banyak digunakan di Jawa daripada di C, atur skor untuk volatilekata kunci menjadi 2 untuk Java dan 1 untuk C.

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;
    }
  }
}
ufis
sumber
4

Hanya beberapa generalisasi luas.

Saya pikir ini cukup akurat.

Ini adalah Ruby btw. Mengambil input (multiline) dari 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
daniero
sumber
Saya pikir #include adalah prediktor yang lebih baik untuk c. Bagaimana dengan #! / Bin / (ba)? Sh untuk skrip bash / shell?
Digital Trauma
@ DigitalTrauma Ya, saya pikir Anda benar tentang #include. Untuk alasan artistik, saya tidak akan menangkap hash-bang di mana nama bahasanya secara eksplisit diucapkan.
daniero
#include adalah komentar dalam inifile danphp
Ismael Miguel
1
+1 karena memiliki prolog, tetapi tidak ada C :)
SztupY
1
Saya akan menambahkan \$\w+setelah perl satu untuk mendeteksi PHP. Juga (\w+)::~\1biasanya sebuah destruktor C ++
SztupY
2

Javascript - 6 bahasa - akurasi tinggi

Bahasa Saat Ini: Java, C, HTML, PHP, CSS, Javascript

Saya bekerja pada prinsip bahwa setiap kali input memenuhi kriteria, itu diberikan skor, dan berdasarkan itu hasil skor diberikan.

Fitur:

  • Tidak ada fungsi bawaan yang menentukan jenis bahasa yang digunakan.
  • Tidak langsung menyatakan teks input adalah xbahasa saat melihat kata kunci.
  • Sarankan bahasa lain yang mungkin juga.

Jika Anda merasa bahwa salah satu input Anda dari program (yang telah saya lakukan sampai sekarang) tidak tertangkap atau mendapatkan hasil yang tidak valid, maka tolong laporkan dan saya akan dengan senang hati memperbaikinya.

Input Sampel 1:

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

Contoh Output 1:

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

Penjelasan:

Seharusnya ini gagal program dan saya akan mencetak PHP, tetapi karena program saya bekerja berdasarkan skor, tidak ada yang gagal dan itu dengan mudah mengidentifikasi Java di tempat pertama, diikuti oleh kemungkinan hasil lainnya.

Input Sampel 2:

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

Contoh Output 2:

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

Input Sampel 3:

ABCDEFGHIJKLMNOPQRSTUVWXYZ

Contoh Output 3:

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

Kode:

// 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("----------------");
Gaurang Tandon
sumber