Bir snippet'in hangi programlama dilini algıladığını tespit etme


23

Buradaki zorluk, girdi olarak bazı kaynak kodları ve hangi programlama dilinde yazıldığı çıktıları almaktır.

Örneğin, giriş

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

Ve çıktı

Java

İki ana hedefiniz çeşitlilik (kaç tane programlama dili tespit edebileceğinizi) ve doğruluk (bu dilleri tespit etmede ne kadar iyi).

Poligonlar için (birden fazla dilde geçerli programlar), ne yapacağınıza karar verebilirsiniz. Programınızın daha muhtemel olduğunu düşündüğü dili çıktısını alabilirsiniz veya bir hata çıktısını alabilirsiniz veya bir dizi olası seçenek çıktısı alabilirsiniz (bu muhtemelen bir hatadan daha fazla puan alır!).

Bu bir , çünkü farklı bir hedef kazanma kriteri belirlemek çok zor olacaktır. Seçmenler, lütfen kaç dili tespit edebileceğini ve ne kadar doğru olduğunu oylayın.


Bu imkansız, çünkü print("")birçok dilde kullanılabilir.
Ismael Miguel,

1
Düzenlemenizle, şimdi daha mümkün görünüyor.
Ismael Miguel,

4
HER giriş için geçerli olan diller nelerdir? Boşluk gibi. Bu cümle geçerli bir boşluk programıdır. Bu sayfanın tamamı geçerli bir boşluk programıdır.
Ismael Miguel,

1
Girişin geçerli bir program olduğu garantili mi? Gibi bazı girişler class A{public static void main(String[]a){System.println.out("Hello, World!");}}geçersiz olabilir.
Gaurang Tandon

1
Ya aynı şekilde HTML girişi daima başlayacak <!DOCTYPE html>, ardından <html>, <body>ve (gibi diğer etiketler metakendi doğru sırayla)?
Gaurang Tandon

Yanıtlar:


18

234 metin formatları - Unix Shell

(hepsi dil değil - onları dikkatlice saymam gerekiyor)

file $1

Bu biraz smart-a $$ cevap göndermek için tereddüt, ama bunu yasaklayan kurallarda hiçbir şey görmüyorum ve filekabuk yardımcı programı gerçekten bu iyi bir iş yapıyor. Örneğin:

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

Ayrıca, -kbir polyglot test ederken "devam et" seçeneğini kullanabilirsiniz :

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

Ayrıca, -lseçenek size algoritmanın farklı diller için ne kadar iyi olduğu konusunda bir fikir verecektir:

$ dosya -l | Grep Shell
bilinmiyor, 0: Uyarı: `/ etc / magic 'normal sihirli dosyasını kullanarak
Dayanıklılık = 280: kabuk arşiv metni [application / octet-stream]
Mukavemet = 250: Tenex C kabuk betiği çalıştırılabilir metni [text / x-shellscript]
Gücü = 250: Bourne-Again kabuk komut dosyası çalıştırılabilir metin [text / x-shellscript]
Gücü = 240: Paul Falstad'ın zsh betiği metni çalıştırılabilir [text / x-shellscript]
Gücü = 240: Neil Brown'ın kül betiği metni çalıştırılabilir [text / x-shellscript]
Gücü = 230: Neil Brown'ın ae script metni çalıştırılabilir [text / x-shellscript]
Gücü = 210: Tenex C kabuk betiği metni çalıştırılabilir [text / x-shellscript]
Gücü = 210: Bourne-Again kabuk komut dosyası çalıştırılabilir metin [text / x-shellscript]
Mukavemet = 190: Tenex C kabuk betiği çalıştırılabilir metni [text / x-shellscript]
Gücü = 190: Bourne-Again kabuk komut dosyası çalıştırılabilir metin [text / x-shellscript]
Gücü = 180: Paul Falstad'ın zsh betiği metni çalıştırılabilir [text / x-shellscript]
Mukavemet = 150: Tenex C kabuk betiği çalıştırılabilir metni [text / x-shellscript]
Gücü = 150: Bourne-Again kabuk komut dosyası çalıştırılabilir metin [text / x-shellscript]
Gücü = 140: C kabuğu betiği metni çalıştırılabilir [text / x-shellscript]
Gücü = 140: Korn kabuğu betiği metni çalıştırılabilir [text / x-shellscript]
Gücü = 140: Paul Falstad'ın zsh betiği metni çalıştırılabilir [text / x-shellscript]
Güç = 130: POSIX kabuk betiği çalıştırılabilir metni [text / x-shellscript]
Gücü = 130: Plan 9 rc kabuk betiği metni çalıştırılabilir []
$ 

Bu file-5.09(Ubuntu 12.04 tarihinde)


Bu aslında 16 dilli bir çok dilde çok iyi gidiyor
gist.github.com/riking/9088817

Siz de orta adam kesmek ve tamamen kabuk önlemek olabilir: ln -s /usr/bin/file /usr/local/bin/myspecialtool. Cevabınız sayarsa, o zaman bu da sayılmaz mı? (Endişelenme, ciddi değilim.)
hvd

2
Standart bir boşluğa benziyor, yani mevcut programa çözüm veriyor.
Vi.

10

Bash - hakkında 50 Derlenebilir dil başına 35 bayt

İşin püf noktası sadece derlemektir, o zaman eksik kütüphanelerdeki hataları bağlamak konusunda endişelenmenize gerek yoktur ve sadece kod parçacıkları varsa daha bağışlayıcıdır.

Kısa formlar için Şahbaz'a teşekkürler!

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)

vb...


Derlenebilir dil başına bayt sayısından söz ettiğinden, şu satırlar ilginizi çekebilir:gcc -c $1 && (echo C; exit 0)
Shahbaz

Teşekkür ederim, gerçekten sıkma kodunda çok iyi değilim!

Emin. &&Ve ||bash kodu bir sürü gerçekten yararlı ve yardım Cleanup vardır. Hiçbir şekilde şaşırtmaca için kullanılmazlar, bu yüzden onları öğrenmek için iyi yaparsınız.
Shahbaz

2
Ayrıca -fsyntax-onlyyalnızca sözdizimini kontrol etmek ve gerçek derlemeyi atlamak için de geçebilirsiniz .
peppe

7

18 programlama dili, 1002 bayt, doğruluk: kendiniz için test edin :)

(Evet, bunun kod golf olmadığını biliyorum, ama eğlencesi için)

Program ikonik kod parçacıklarını arar, kontroller en net kontrollerin en üstte olduğu şekilde sıralanır ve diğer programlama dillerinde gömülü olan programlama dilleri aşağıdadır (örneğin, PHP'de HTML).

Bu açıkça gibi programlar için başarısız 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

Düğümde kullanım: coffee timwolla.coffee < Example.java

Demo ( JSFiddle'da Çevrimiçi Demo ):

[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

Bilgisayarımda bu açık bir şekilde çalışması gereken girdilerde bile hiçbir şey vermiyor. Verilmiş, daha önce hiç Coffeescript kullanmadığım için yanlış bir şey yapıyor olabilirim.
marinus

@marinus Kodu manuel olarak girerken, yürütmeyi tetiklemek için bir EOF (STRG + D) göndermeniz gerektiğini unutmayın. Genel olarak: Dedektör en az üç soru işaretini dağıtmalıdır.
TimWolla

Hayır, hiçbir şey. Ben geçmesi gerekiyor mu coffeeherhangi bir bağımsız değişken? Dosyaları yeniden yönlendirmeyi denemiştim, ancak çalıştırıyor ve gidiyor ^Dda hiçbir şey yapmıyor.
marinus

@ marinus Dene: npm install coffee-script && node_modules/.bin/coffee timwolla.coffee < timwolla.coffeegeçici bir klasörde bunun tükürmesi gerekir APL. (düğüm ve npm'nin en son sürümüne sahip olduğunuzu varsayarak)
TimWolla

5
APL olmayan programlarımda daha küçük harfli omega kullanmaya başlayacağım.
John Dvorak

4

Bu cevap, kendimden daha fazla iş almayacak bir kavram kanıtıdır.

Birkaç şekilde kısalır:

  • Çıktı tam olarak soru talepleri değil, ancak yeterince yakındır ve gereken tam çıktının üretilmesi için kolayca değiştirilebilir.
  • Veri yapılarını temsil etmek için kodun daha iyi ve / veya daha iyi performans göstermesini sağlamanın birkaç yolu vardır.
  • ve dahası

Buradaki fikir, belirli bir dili tanımlayabilecek ve her bir dil için o anahtar kelimeye bir puan atayabilecek bir anahtar kelime / karakter / kelime öbeği listesi oluşturmaktır. Ardından, bu anahtar kelimeler için kaynak dosyaları inceleyin ve anahtar kelimeleri bulduğunuz her dilin puanlarını toplayın. Sonunda en yüksek puana sahip dil ​​muhtemel kazanandır. Bu aynı zamanda polglot programlarına da hitap eder, çünkü ilgili dillerin ikisi de (veya tümü) yüksek puan alır.

Daha fazla dil eklemek için tek şey onların "imzalarını" tanımlamak ve haritaya eklemek.

Dil başına farklı anahtar kelimelere farklı puanlar atayabilirsiniz. Örneğin, volatileJava’da C’den daha fazla kullanıldığını düşünüyorsanız , volatileanahtar kelime için puanı Java için 2 ve C için 1 olarak ayarlayın.

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

Sadece birkaç genelleme.

Bence oldukça doğru.

Bu Ruby Btw. Stdin'den (multiline) girdi alır.

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

#İnclude'in c için daha iyi bir tahmin olduğunu düşünüyorum. Peki ya #! / Bin / (ba)? Bash / shell scriptleri için sh?
Dijital Travma

@DigitalTrauma Yea, #include konusunda haklı olduğunuzu düşünüyorum. Sanatsal nedenlerden dolayı, sadece dilin adının açıkça söylendiği karma-bang'ı yakalamayacağım.
daniero

#include inidosyalardaki bir yorumdur vephp
Ismael Miguel

1
Prolog

1
Ben eklersiniz \$\w+PHP algılamak için perl birinden sonra. Ayrıca (\w+)::~\1genellikle bir C ++ yıkıcısıdır
SztupY

2

Javascript - 6 dil - yüksek doğruluk

Mevcut Diller: Java, C, HTML, PHP, CSS, Javascript

Ne zaman bir girdi ne zaman bir kritere uygunsa, ona bir puan verildiği ve o sonuçlara dayanarak verilen ilke üzerinde çalışıyorum.

Özellikler:

  • Kullanılan dil türünü belirleyen yerleşik işlevler yok.
  • Hemen girilmezse, giriş metninin xbir anahtar kelimeyi görmenin dili olduğunu beyan etmez .
  • Diğer olası dilleri de önerir.

Program girişlerinden herhangi birinin (şu ana kadar yaptığım) yakalanmadığını ya da geçersiz sonuç almadığını düşünüyorsanız, lütfen rapor verin ve bunları düzeltmekten memnuniyet duyarım.

Örnek Giriş 1:

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

Örnek Çıkışı 1:

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

Açıklama:

Bu program başarısız olmuş ve yazdırmalıydım PHP, ancak programım puanlar temelinde çalıştığı için hiçbir şey başarısız olmuyor ve ilk etapta Java'yı kolayca belirliyor, ardından diğer olası sonuçlar geliyor.

Numune Girişi 2:

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

Örnek Çıkışı 2:

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

Örnek Giriş 3:

ABCDEFGHIJKLMNOPQRSTUVWXYZ

Numune Çıkışı 3:

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

Kod:

// 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("----------------");
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.