Detectar qual linguagem de programação é um trecho


23

Seu desafio é pegar um código-fonte como entrada e exibir em qual linguagem de programação ele está escrito.

Por exemplo, você poderia ter a entrada

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

E saída

Java

Seus dois objetivos principais são diversidade (quantas linguagens de programação você pode detectar) e precisão (quão bom você é na detecção dessas linguagens).

Para poliglotas (programas válidos em mais de um idioma), você pode decidir o que fazer. Você pode apenas produzir a linguagem que seu programa considera mais provável, ou você pode gerar um erro, ou você pode produzir uma variedade de opções possíveis (que provavelmente receberiam mais votos do que apenas um erro!).

Este é um , porque seria muito difícil especificar um critério de vitória objetivo diferente. Eleitores, vote em quantos idiomas ele pode detectar e em quão preciso é.


Isso é impossível, porque a causa print("")pode ser usada em vários idiomas.
Ismael Miguel

1
Com sua edição, agora parece mais possível.
Ismael Miguel

4
E os idiomas válidos para TODAS as entradas? Como espaço em branco. Esta frase é um programa de espaço em branco válido. Esta página inteira é um programa de espaço em branco válido.
Ismael Miguel

1
A entrada é garantida como um programa válido? Como alguma entrada poderia ser class A{public static void main(String[]a){System.println.out("Hello, World!");}}inválida.
Gaurang Tandon

1
Ou irá também input HTML sempre começar com <!DOCTYPE html>seguido pelo <html>, <body>e outras tags (como meta) em sua ordem correta?
Gaurang Tandon

Respostas:


18

234 formatos de texto - Unix Shell

(nem todos os idiomas - preciso contá-los com cuidado)

file $1

Hesito em postar essa resposta um tanto inteligente - uma $$ -, mas não vejo nada nas regras que a proíbam e o fileutilitário shell realmente faz um bom trabalho nisso. por exemplo:

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

Além disso, você pode usar a -kopção de "continuar" ao testar um poliglota:

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

Além disso, a -lopção fornecerá uma idéia de quão bom é o algoritmo para diferentes idiomas:

$ arquivo -l | grep shell
desconhecido, 0: Aviso: usando o arquivo mágico regular `/ etc / magic '
Strength = 280: texto do arquivo de shell [application / octet-stream]
Força = 250: texto do script do shell Tenex C executável [text / x-shellscript]
Força = 250: texto do script de shell Bourne-Again executável [text / x-shellscript]
Strength = 240: Texto do script zsh de Paul Falstad executável [text / x-shellscript]
Força = 240: Texto em cinza do script de Neil Brown executável [text / x-shellscript]
Força = 230: texto ae de Neil Brown, executável, texto [text / x-shellscript]
Força = 210: texto do script de shell Tenex C executável [text / x-shellscript]
Força = 210: texto do script de shell Bourne-Again executável [text / x-shellscript]
Força = 190: texto do script de shell Tenex C executável [text / x-shellscript]
Força = 190: texto do script de shell Bourne-Again executável [text / x-shellscript]
Força = 180: texto do script zsh de Paul Falstad executável [text / x-shellscript]
Força = 150: texto do script de shell Tenex C executável [text / x-shellscript]
Força = 150: texto do script de shell Bourne-Again executável [text / x-shellscript]
Força = 140: texto do script de shell C executável [text / x-shellscript]
Força = 140: Texto do script de shell Korn executável [text / x-shellscript]
Força = 140: Texto do script zsh de Paul Falstad executável [text / x-shellscript]
Força = 130: texto do script de shell POSIX executável [text / x-shellscript]
Força = 130: Planeje o texto do script do shell 9 rc executável []
$ 

Isto é file-5.09(no Ubuntu 12.04)


Isso realmente funciona muito bem em um poliglota de 16 idiomas - gist.github.com/riking/9088817
Riking

Assim como você pode cortar o homem médio e evitar o shell inteiramente: ln -s /usr/bin/file /usr/local/bin/myspecialtool. Se sua resposta conta, isso não conta também? (Não se preocupe, eu não falo sério.) #
191

2
Parece uma brecha padrão, ou seja, delegar solução ao programa existente.
Vi.

10

Bash - sobre 50. 35 bytes por idioma compilável

O truque é apenas compilar, então você não precisa se preocupar em vincular erros de bibliotecas ausentes, e é mais indulgente se você tiver apenas trechos de código.

Obrigado a Shahbaz pelas formas mais curtas!

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)

etc ...


Como você mencionou o número de bytes por idioma compilável, você pode estar interessado em linhas como:gcc -c $1 && (echo C; exit 0)
Shahbaz

Obrigado, eu não sou muito bom em realmente espremer código!

Certo. O &&e ||no bash são realmente úteis e ajudam bastante na limpeza do código. Eles não são de forma alguma usados ​​para ofuscar, então você faria bem em aprendê-los.
Shahbaz

2
Você também pode passar -fsyntax-onlypara verificar apenas a sintaxe e pular a compilação real.
peppe

7

18 linguagens de programação, 1002 bytes, precisão: teste você mesmo :)

(sim, eu sei que isso não é código de golfe, mas por diversão)

O programa procura trechos de código icônicos, as verificações são ordenadas de forma que as verificações mais claras estejam no topo e as linguagens de programação incorporadas em outras linguagens de programação estejam abaixo (por exemplo, HTML em PHP).

Obviamente, isso falha em programas como 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

Uso no nó: coffee timwolla.coffee < Example.java

Demo (Demo Online no 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

No meu computador, isso não gera nada, nem mesmo na entrada que obviamente deveria funcionar. É verdade que posso estar fazendo algo errado, pois nunca usei o Coffeescript antes.
marinus

@marinus Observe que, ao inserir manualmente o código, você precisa enviar um EOF (STRG + D) para acionar a execução. Geralmente: o detector deve cuspir pelo menos três pontos de interrogação.
19414 TimWolla

Não, nada. Preciso passar coffeealgum argumento? Eu apenas tentei redirecionar arquivos para ele, mas apenas executá-lo e seguir em frente ^Dtambém não faz nada.
marinus

Marinus @ Tente: npm install coffee-script && node_modules/.bin/coffee timwolla.coffee < timwolla.coffeeem uma pasta temporária, isso deve cuspir APL. (supondo que você tem uma versão recente do nó e NPM instalado)
TimWolla

5
Começarei a usar omega minúsculo mais em meus programas não-APL.
John Dvorak

4

Essa resposta é uma prova de conceito que provavelmente não receberá mais trabalho de mim mesmo.

Ele fica aquém de várias maneiras:

  • A saída não é exatamente como a pergunta solicita, mas é suficientemente próxima e pode ser facilmente modificada para produzir a saída exata necessária.
  • Existem várias maneiras de fazer com que o código tenha um desempenho melhor e / ou melhores para representar as estruturas de dados.
  • e mais

A idéia é definir uma lista de palavras-chave / caracteres / frases que possam identificar um idioma específico e atribuir uma pontuação a essa palavra-chave para cada idioma. Em seguida, verifique o (s) arquivo (s) de origem para essas palavras-chave e calcule as pontuações de cada idioma para o qual você encontra palavras-chave. No final, o idioma com a pontuação mais alta é o provável vencedor. Isso também serve para programas poliglotas, pois ambos (ou todos) os idiomas relevantes terão uma pontuação alta.

A única coisa para adicionar mais idiomas é identificar suas "assinaturas" e adicioná-las ao mapeamento.

Você também pode atribuir pontuações diferentes a diferentes palavras-chave por idioma. Por exemplo, se você acha que volatileé usado mais em Java do que em C, defina a pontuação da volatilepalavra-chave como 2 para Java e 1 para 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;
    }
  }
}

4

Apenas algumas amplas generalizações.

Eu acho que é bastante preciso.

Aqui é Ruby. Recebe entrada (multilinha) de 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

Eu acho que #include é um melhor preditor para c. E o #! / Bin / (ba)? Sh para scripts bash / shell?
Digital Trauma

@DigitalTrauma Sim, acho que você está certo sobre #include. Por razões artísticas, não vou apenas pegar o hash-bang, onde o nome do idioma está explicitamente explicitado.
Daniero

#include é um comentário nos iniarquivos ephp
Ismael Miguel

1
1 por ter Prolog, mas não C :)
SztupY

1
Eu acrescentaria \$\w+depois do perl para detectar o PHP. Também (\w+)::~\1é geralmente um processo de destruição de C ++
SztupY

2

Javascript - 6 idiomas - alta precisão

Idiomas Atuais: Java, C, HTML, PHP, CSS, Javascript

Trabalho com o princípio de que, sempre que uma entrada satisfaz um critério, ela recebe uma pontuação e, com base nessa pontuação, os resultados são fornecidos.

Recursos:

  • Não há funções internas que determinam o tipo de idioma usado.
  • Não declara imediatamente que o texto de entrada é o xidioma ao ver uma palavra-chave.
  • Também sugere outros idiomas prováveis.

Se você sentir que alguma das entradas dos programas (que eu fiz até agora) não foi capturada ou não obteve resultados inválidos, informe-nos e ficarei feliz em corrigi-las.

Entrada de amostra 1:

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

Saída de amostra 1:

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

Explicação:

Isso deveria ter falhado no programa e eu teria impresso PHP, mas como meu programa funciona com base em pontuações, nada falha e ele identifica facilmente o Java em primeiro lugar, seguido por outros resultados possíveis.

Entrada de amostra 2:

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

Saída de amostra 2:

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

Entrada de amostra 3:

ABCDEFGHIJKLMNOPQRSTUVWXYZ

Saída de amostra 3:

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

O código:

// 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("----------------");
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.