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).
computability
programming-languages
compilers
Tobi Alafin
fonte
fonte
Respostas:
TLDR; isso é possível, mas não prático.
Isso acaba sendo um pouco complicado, e é parte do motivo pelo qual coisas como essa não acabam sendo usadas na prática.
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.
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á:
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.
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.
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.
fonte
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.
fonte
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 #.
fonte
Para o seu caso de uso (com base nos comentários), parece que SWIG pode ser útil.
fonte
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.
fonte
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.
fonte