A maioria das linguagens de programação é Turing completa, o que significa que qualquer tarefa que possa ser resolvida em uma linguagem pode ser resolvida em outra ou mesmo na máquina de Turing. Então, por que não existem tradutores automáticos que podem converter programas de um idioma para outro idioma? Já vi algumas tentativas para dois idiomas, mas eles sempre funcionam apenas em um subconjunto limitado de um idioma e dificilmente podem ser usados para converter projetos reais.
É possível, pelo menos em teoria, escrever um tradutor 100% correto entre todas as línguas? Quais são os desafios na prática? Existem tradutores existentes que funcionam?
Respostas:
O maior problema não é a tradução real do código do programa, mas a portabilidade da API da plataforma.
Considere um tradutor de PHP para Java. A única maneira viável de fazer isso sem incorporar parte do binário PHP é reimplementar todos os módulos e APIs do PHP em Java. Isso envolve a implementação de mais de 10.000 funções. Comparado a isso, o trabalho de realmente traduzir a sintaxe é fácil. E mesmo depois de todo esse trabalho, você não teria código Java, teria algum tipo de monstruosidade que é executada na plataforma Java, mas que foi estruturada como PHP por dentro.
É por isso que as únicas ferramentas que vêm à mente são sobre a tradução de código para implantá-lo, e não para mantê-lo posteriormente. O GWT do Google "compila" Java para JavaScript. O hiphop do Facebook compila PHP em C.
fonte
Se você tem um formato intermediário, então você poderia implementar algo que traduz um programa em Língua X para esse formato, e também de que o formato de Y. Idioma Implementar essas conversões para todos os idiomas que você está interessado e está feito, certo?
Bem, você sabe o que? Esse formato já existe: assembly. O compilador já faz a conversão "Linguagem X para montagem" e desmontadores para a conversão "assembly para Linguagem Y".
Agora, assembly não é uma linguagem tão boa para fazer a conversão reversa, mas o MSIL não é tão ruim assim. Faça o download do Reflector e você verá que há opções para desmontar um assembly .NET em vários idiomas diferentes (e os plugins fornecem ainda mais). Portanto, é bem possível pegar um programa em C #, compilá-lo em uma DLL (ou seja, MSIL) e usar o refletor para desmontá-lo em VB, C ++ / CLI, F # e muitos outros. Obviamente, todas as outras conversões também funcionam. Pegue um arquivo F #, compile em uma DLL, use o Reflector para convertê-lo em C #.
Obviamente, os dois grandes problemas que você encontrará são:
Não há realmente nada para contornar o número 2, mas você provavelmente poderia contornar o número 1 com algumas anotações adicionais no MSIL (via atributos, talvez). Isso seria um trabalho adicional, é claro.
fonte
Microsoft.NET\Framework\v2.0.50727\en
por exemplo, poderá ver toda a documentação XML das bibliotecas do sistema. É isso que Reflector (et al) usa para exibir os comentários. A conversão não é ilegível, tudo o que eu estava dizendo é que não é 100% de fidelidade que você pode esperar de uma tradução no nível da fonte.fonte
Por que você deseja converter um programa?
Ambos os idiomas, o idioma de origem e o destino são compilados para o código de máquina (virtual) de qualquer maneira *, portanto, por razões técnicas, não é necessário ter um compilador para outro idioma de alto nível.
Idiomas são para humanos. Portanto, o requisito implícito da sua pergunta é: 'por que não há tradutor que gere código legível ' e a resposta seria (imho): porque se houver duas línguas suficientemente diferentes, as formas 'código legível' serão escritas é diferente de uma maneira que não exige apenas a conversão dos algoritmos, mas usa algoritmos diferentes.
Por exemplo, compare uma iteração típica em C e uma no lisp. Ou pitões 'de uma maneira melhor' com rubi idiomático.
Aqui, os mesmos problemas começam a aparecer em idiomas reais, como você traduz 'Está chovendo gatos e cães' para algo com o significado de 'Está derramando como faria em baldes' ao traduzir de inglês para alemão, você não pode traduza mais palavra por palavra, mas você deve procurar o significado.
E 'significado' não é um conceito fácil de se trabalhar.
*) bem, há café ...
fonte
É teoricamente possível, mas principalmente inútil. Quase qualquer combinação de idiomas de origem e de destino é possível, mas na maioria dos casos, ninguém gostaria de ver ou usar o resultado.
Um número razoável de compiladores tem como alvo C, simplesmente porque os compiladores C estão disponíveis para quase todas as plataformas existentes (e existem geradores automáticos de compiladores que permitem projetar um processador e gerar automaticamente um compilador C destinado ao seu novo processador). Também existe, é claro, um número razoável de implementações que têm como alvo os idiomas usados por várias máquinas virtuais, como .NET, JVM, C-- e LLVM.
O ponto-chave, no entanto, é que ele realmente é útil apenas se você tratar o destino como basicamente uma linguagem assembly que é usada apenas como uma etapa no processo de compilação. Em particular, você geralmente não deseja que um programador normal leia ou trabalhe com esse resultado; geralmente não será muito legível.
fonte
FWIW, existe um tradutor de Java para D. Ele se chama TioPort e foi usado em uma tentativa bastante séria de portar SWT para D. O principal problema foi o de que seria necessário portar grandes partes da biblioteca padrão Java .
fonte
Embora não seja a tradução de código em si, o conceito de bancadas de idiomas mostra como algo semelhante a um tradutor 100% correto entre todos os idiomas pode ser implementado.
Em nossa abordagem atual, o código fonte é armazenado em um formato textual. Durante a compilação, esses arquivos de texto legíveis por humanos são analisados em uma representação abstrata da árvore de sintaxe, que por sua vez é usada para gerar bytecode ou código de máquina. Essa representação abstrata, no entanto, é temporária e interna ao compilador.
Na abordagem do ambiente de trabalho de idiomas, uma representação de árvore de sintaxe abstrata semelhante é o artefato armazenado permanente. O código da máquina e o código 'fonte' textual são gerados com base nessa representação abstrata. Uma das consequências de tal método é que a representação abstrata do programa é realmente independente da linguagem e pode ser usada para gerar código textual em qualquer linguagem implementada. Significando que uma pessoa pode trabalhar livremente em diferentes aspectos do sistema usando o idioma que considerar mais adequado ou cada membro da equipe pode trabalhar no projeto compartilhado no idioma com o qual está mais familiarizado.
Até onde eu sei, a tecnologia ainda está longe de ser utilizável no desenvolvimento convencional, no entanto, existem vários grupos trabalhando nela independentemente. Difícil dizer se algum deles cumprirá suas promessas, mas seria interessante ver isso acontecer.
fonte
Não são alguns tradutores automáticos. Se seu objetivo é produzir código compilável, em vez de legível, é bem possível e ocasionalmente útil, mas não com muita frequência. Famosamente, o primeiro compilador C ++ não era realmente um compilador, mas traduziu C ++ para uma fonte C (realmente complicada) que foi então compilada pelo compilador C. Muitos compiladores podem gerar código de montagem a pedido - mas, em vez de cuspir o texto de montagem e convertê-lo em código de máquina, normalmente eles podem gerar código de máquina diretamente.
Dada uma especificação completa da linguagem A, não é tão difícil, em princípio, escrever um programa que expresse suas diretivas em alguma linguagem B. Mas, geralmente, qualquer pessoa que se dê ao trabalho de escolher um nível realmente baixo para a "linguagem B": Código da máquina , ou nos dias de hoje bytecode: Jython é uma implementação de python que gera código java byte, que é interpretado pela Java VM. Não há necessidade de escrever e compilar hierarquias de classes java!
fonte
Isso é feito o tempo todo.
Todo compilador converte o "idioma primário", como C ++, na linguagem assembly nativa da máquina ou no bytecode independente da arquitetura, no caso de linguagens interpretadas.
Eu imagino que não é disso que você está falando, no entanto. Você provavelmente deseja um tradutor que converta C ++ em algo como Java ou Python. Qual é o sentido disso? Na melhor das hipóteses, o resultado final terá exatamente a mesma eficiência que a fonte original. (Praticamente, será muito pior.)
Se você apenas deseja que o código seja traduzido para poder lê-lo como um idioma que você entende, esse tradutor terá o oposto do efeito desejado. Você ficará com uma série de códigos enigmáticos, não intuitivos e ilegíveis.
Isso ocorre porque apenas as coisas mais triviais traduzem diretamente de um idioma para outro. Muitas vezes, o que é simples em um idioma requer bibliotecas enormes para outro - ou pode ser impossível por completo. Assim sendo:
No final, a única maneira de escrever um bom código é realmente escrevê-lo. Os computadores simplesmente não podem - pelo menos ainda não - combinar os humanos em questões de legibilidade, melhores práticas e soluções elegantes.
Em suma, simplesmente não vale a pena.
fonte
Não há tradutores de idiomas para linguagens de programação porque as linguagens de programação são incrivelmente complexas. Embora seja hipoteticamente possível, há muitos desafios.
O primeiro desafio está apenas nas práticas aceitáveis da linguagem. A conversão entre duas linguagens orientadas a objetos, como Java e C ++, é incrivelmente complexa e ambas são baseadas em C. O programa tradutor teria que ter conhecimento perfeito das bibliotecas padrão para os dois idiomas e ser capaz de conhecer as diferenças de comportamento. Você precisaria criar um dicionário enorme e, mesmo assim, as diferenças nos estilos de programação de programador para programador significariam que seria preciso adivinhar como executar algumas alterações.
Depois de obter a tradução da sintaxe, é necessário descobrir como converter uma construção no primeiro idioma em uma construção no segundo idioma. Isso é bom se você estiver indo de um objeto em C ++ para um objeto em Java (comparativamente fácil), mas o que você faz com suas estruturas de C ++? Ou as funções fora das classes C ++? Decidir como lidar com isso pode ser complicado, pois pode resultar em outro problema, a saber, a criação de um objeto de blob. O blob é um antipadrão que é bastante comum.
Esta não é uma lista completa dos problemas, mas esses são apenas dois e são grandes. Um dos meus professores mencionou que alguém convenceu seu empregador de que poderia fazer um código de máquina para C nos anos 80, mas não funcionou na época. Duvido que algum dia funcione plenamente.
fonte
O objetivo da compilação é obter algo útil para o computador. ou seja, algo que pode ser executado. Por que compilar com algo que pode até ser de nível superior ao que você escreveu?
Eu gosto mais da estratégia do .NET. Compile tudo para um idioma comum. Isso oferece o benefício de os idiomas poderem se comunicar sem a necessidade de criar compiladores de idiomas cruzados (N ^ 2) -N.
Por exemplo, se você tivesse 10 linguagens de programação, seria necessário escrever apenas 10 compiladores no modelo .NET e todos eles poderiam se comunicar. Se você criou todos os compiladores possíveis em vários idiomas, precisará escrever 90 compiladores. Isso é muito trabalho extra para pouco benefício.
fonte