Existem programas que podem 'traduzir' o código fonte entre dois idiomas?

28

Existem programas que podem 'traduzir' o código fonte entre dois idiomas (assumindo que o tradutor tenha acesso às bibliotecas necessárias)?

Se houver, como eles funcionam (técnicas utilizadas, conhecimento necessário etc.)? Como eles poderiam ser construídos?

Se não estiverem, quais são as restrições que impedem seu desenvolvimento? Esse é um problema completo da IA ​​(a tradução do idioma natural é listada como um)?

A conversão EDIT é esperada apenas quando o idioma tem o mesmo poder de expressão, pode resolver o mesmo tipo de problemas e o código a ser convertido pode ser expresso no idioma de destino. (Por exemplo, a conversão de um script de shell para MATLAB não é esperada).

Tobi Alafin
fonte
14
O que você quer dizer com "dois idiomas"? Certamente existem programas que podem traduzir de um idioma para outro. Eles são chamados de "compiladores". Essa é literalmente a definição de um compilador: um programa que traduz programas de um idioma para outro. Mas "duas línguas"? Eu não acho isso possível. O tradutor precisa conhecer o idioma de origem e o destino, e geralmente é específico para um par específico de idiomas.
Jörg W Mittag
O programa é fornecido com os idiomas de origem e de destino. Estou pensando em escrever um programa em C ++, traduzi-lo para Java, python, Perl, Ruby, Go, etc. Pode haver algumas restrições (não espero que ele converta seu shell script para MATLAB, por exemplo).
quer
4
Sim, eles são chamados de compiladores, funcionam como compiladores e podem ser construídos como compiladores.
user253751
11
Se por "dois idiomas" você literalmente quer dizer que o programa (finito) deve ser capaz de ler e entender um número infinito de idiomas de entrada, a resposta é trivialmente não . No entanto, tome um conjunto finito de idiomas de entrada e você pode encontrar um compilador para todos esses idiomas ..
Bakuriu

Respostas:

57

TLDR; isso é possível, mas não prático.

(supondo que o tradutor tenha acesso às bibliotecas necessárias)?

Isso acaba sendo um pouco complicado, e é parte do motivo pelo qual coisas como essa não acabam sendo usadas na prática.

  1. Todos os compiladores são tradutores. Traduzir de um idioma para outro é definitivamente possível, e isso é literalmente tudo o que um compilador está fazendo. O idioma que um compilador cospe como saída geralmente é código de máquina ou assembly, mas esse é apenas outro idioma, e existem compiladores (às vezes chamados de transpilers ou transcompilers) que são traduzidos entre dois idiomas . Por exemplo, existe uma gama de linguagens de compilação em Javascript, como PureScript, Elm, ClojureScript, etc.

  2. A tradução entre dois idiomas do Turing Complete é sempre possível. Ignorar coisas como chamadas de biblioteca e FFI e outros bits práticos desagradáveis ​​que atrapalham, é isso. Se um idioma for Turing Complete, você terá:

    • Uma tradução que converte uma Máquina de Turing em código neste idioma
    • Uma tradução deste idioma para uma máquina de Turing

    Portanto, para traduzir do idioma A para o idioma B, você converte o código A em uma Máquina de Turing e depois converte essa máquina em código B.

    Obviamente, na prática, os aspectos práticos atrapalham, e isso também exige que você tenha as traduções acessíveis a você. Eles existem basicamente para todos os idiomas, mas isso não significa que alguém tenha tempo para escrevê-los.

  3. Fazer essa tradução com eficiência é difícil . Linguagem diferente prioriza coisas diferentes. Por exemplo, se você traduzir de C para Python, provavelmente terá que simular a memória de C como um dicionário Python, para poder fazer aritmética de ponteiros. Haverá sobrecarga associada a isso, porque agora você não está acessando as instruções de memória bare metal.

    Idiomas diferentes têm prioridades de desempenho diferentes; portanto, algo que um idioma otimiza (ou melhor, a implementação de um idioma otimiza) pode ser impossível de ser feito rapidamente em outro idioma. A tradução de um idioma funcional com chamadas de chamada adequadas terá abrandamento se você a traduzir para um idioma sem chamadas de chamada apropriadas.

  4. Fazer essa tradução não torna o código legível . É fácil obter um pedaço de código na linguagem B que se comporta da mesma forma que o código da linguagem A. É difícil fazer parecer que o código que um ser humano teria escrito em B, por vários motivos. A e B podem ter diferentes ferramentas de abstração, e o computador não tem idéia do que torna o código legível. Isso será particularmente verdadeiro se você acabar usando a tradução de máquina de Turing que descrevi anteriormente.

    Isso levanta a questão: qual é o sentido dessa tradução? Se tudo o que você obtém no final é um bloco de código lento e ilegível, por que não compilá-lo no código de máquina e usar algum tipo de FFI ou comunicação entre processos para unir as peças?

    Existem algumas exceções a isso. Às vezes, você precisa de coisas em um determinado idioma (como JavaScript). Às vezes, a linguagem é semelhante e uma tradução sensata é fácil. Às vezes, um idioma não deve ser executado, mas ter seu código extraído para outro idioma (como Coq).

    Mas, em geral, não é uma coisa muito prática.

jmite
fonte
5
Um exemplo para o ponto 4 é asm.js . Hoje, é possível fazê-lo sorta legível, usando Javascript Fonte Mapas e do Inspector Element, mas ninguém vai querer fazer isso ...
Ismael Miguel
11
Modelica é outro exemplo de uma linguagem projetada para compilação em outra linguagem (neste caso, C).
Reponha Monica
Webassembly traduzindo de C ++ para javascript.
Surt
Existem inúmeros exemplos de transpilers de X para Y, mas isso é diferente de um compilador universal de qualquer coisa para qualquer coisa. Obviamente existem casos em que transpilar faz sentido.
jmite
Uma exceção importante ausente do IMO: compilando para C. O motivo é que muitos sistemas incomuns possuem um compilador C existente, que geralmente pode emitir um código de máquina bastante razoável. Portanto, ao compilar uma linguagem para C, você não precisa ter back-end para essas arquiteturas raras.
MSalters
2

Existem tais programas. Por exemplo, tradutores Lisp para Fortran, que eram amplamente usados ​​na época. Os compiladores únicos do Lisp não compilam o Lisp diretamente, mas geram o código C, que é compilado por um compilador C regular. Outro exemplo seria Vala que não é compilado diretamente, mas primeiro traduzido para C ++ antes que o código C ++ seja compilado. O Qt é escrito em MOC, um idioma que é traduzido para C ++ para compilá-lo (mas como o MOC é apenas C ++ com alguns comandos adicionais, pode-se argumentar se realmente deve ser chamado de "novo idioma") - e antes disso eram compiladores C ++, havia tradutores C ++ - para C. E alguns projetos foram escritos em Pascal e depois traduzidos para C. Além disso, clang e Java tendem a ser algo que traduz o código C ++ e Java para alguma linguagem intermediária que pode ser processada posteriormente.

O que você não pode esperar da saída de um tradutor de idiomas é que o resultado faça algum sentido para um leitor humano: A tarefa do programa é escrever um código que resulte em um programa fazendo o mesmo que o código original (que na minha experiência pode ou não não funciona, dependendo de quais recursos do idioma e de quais bibliotecas externas você estava usando). Mas, como não sabe o objetivo dessa tarefa, o restante do significado do programa pode ser perdido em grande parte.

Gunter Königsmann
fonte
0

Não é uma resposta direta, mas existe uma ferramenta chamada ILSpy , que foi escrita para o .Net Framework, e permite descompilar um assembly .Net em C # ou VB.Net.

Se você não estiver familiarizado com a natureza do .Net, poderá escrever o código .Net em vários idiomas, mas principalmente em C # ou VB.Net. Quando o compilador compila o aplicativo, ele converte o código em um código "Intermediate Language" (ou IL, abreviado). Esse código é então compilado em binários .Net.

Como os aplicativos .Net são binários compilados a partir do código IL, o ILSpy pode levar o aplicativo .Net, reverter para código IL e, posteriormente, dar um passo adiante e reverter para C # ou VB.Net.

Usando essa ferramenta, tudo que você precisa fazer é compilar um aplicativo e, em seguida, você pode procurar os arquivos compilados como código IL, C # ou VB.Net. Para ser claro, não importa em que idioma o código foi escrito inicialmente. Desde que o binário seja um assembly .Net, ele pode fazer engenharia reversa dos arquivos compilados e gerar o conteúdo como qualquer um desses três idiomas.

Eu sei que isso não é exatamente um compilador, mas é uma ferramenta que oferece um resultado final semelhante ao que você está procurando e, de fato, eu usei isso para "traduzir" projetos VB.Net em algo um pouco mais familiar para mim-- C #.

RLH
fonte
0

Para o seu caso de uso (com base nos comentários), parece que SWIG pode ser útil.

SWIG é uma ferramenta de desenvolvimento de software que conecta programas escritos em C e C ++ com uma variedade de linguagens de programação de alto nível. O SWIG é usado com diferentes tipos de linguagens de destino, incluindo linguagens de script comuns, como Javascript, Perl, PHP, Python, Tcl e Ruby. A lista de idiomas suportados também inclui linguagens sem scripts, como C #, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), linguagem D, Go, Java incluindo Android, Lua, Modula-3, OCAML, Octave, Scilab e R Também são suportadas várias implementações de esquema interpretadas e compiladas (Guile, MzScheme / Racket, Chicken).

Nathan Ringo
fonte
0

Lembro-me do venerável f2c , que faz a tradução de fonte a fonte do Fortran 77 para C.

Foi (às vezes é ...) usado principalmente para traduzir código numérico de décadas atrás, sem a necessidade de integrar um compilador fortran à sua cadeia de ferramentas.

Alexandre C.
fonte
0

A parte da teoria que diz que esses programas existem, em princípio, é chamada numeração admissível . Podemos provar que existem compiladores computáveis ​​entre essas duas numerações, e todo formalismo completo de Turing (ou linguagem de programação) é, em essência, um.

Rafael
fonte