¿Por qué no hay traductores automáticos de un lenguaje de programación a otro? [cerrado]

37

La mayoría de los lenguajes de programación son completos de Turing, lo que significa que cualquier tarea que se pueda resolver en un idioma se puede resolver en otro, o incluso en la máquina de Turing. Entonces, ¿por qué no hay traductores automáticos que puedan convertir programas de cualquier idioma a otro idioma? He visto un par de intentos para dos idiomas, pero siempre funcionan solo en un subconjunto limitado de un idioma y difícilmente se pueden usar para convertir proyectos reales.

¿Es posible, al menos en teoría, escribir un traductor 100% correcto entre todos los idiomas? ¿Cuáles son los desafíos en la práctica? ¿Hay traductores existentes que funcionen?

serg
fuente
55
Recuerde, "todos los idiomas" incluye incluso los estúpidos como Oook! (Turing integridad no es toda la historia, que hay las llamadas al sistema demasiado en la práctica.)
Donal Fellows
Hay algunos. Los traductores de C a Pascal y Pascal a C fueron bastante comunes en un punto. Como sugieren las respuestas a continuación, el resultado generalmente no era tan legible sin al menos un poco de limpieza manual. Y estos son lenguajes relativamente simples con bibliotecas relativamente simples: hacer un buen trabajo, por ejemplo, para C ++ a Haskell o viceversa, probablemente sería imposible.
Steve314
Echa un vistazo a Roslyn, el compilador .net como un servicio que tiene la capacidad de traducir C # a VB y viceversa.
Daniel Little, el
2
Todos los compiladores traducen un PL a otro, sin embargo, no garantizan que el código en el PL objetivo sea fácil de leer
jk.
Después de ver la precisión del traductor de Google, estoy convencido de que veré un traductor universal en mi vida. Sí, va a ser un esfuerzo desafiante y puede requerir un gran esfuerzo como en el caso del análisis de una base de código grande como github o stackoverflow, pero esto sucederá y la demanda de una herramienta de este tipo también aumentará en las próximas edades, ahora especialmente que hay un buen número de programadores para estudiar IA y ML. Es posible que no haya una persona que desarrolle dicha herramienta solo. Sin embargo, uno podría desarrollar un bot para desarrollar bots para abordar este problema.
Ganesh Kamath - 'Code Frenzy' el

Respuestas:

32

El mayor problema no es la traducción real del código del programa, sino la portabilidad de la API de la plataforma.

Considere un traductor de PHP a Java. La única forma factible de hacerlo sin incrustar parte del binario de PHP es volver a implementar todos los módulos y API de PHP en Java. Esto implica implementar más de 10.000 funciones. En comparación con eso, el trabajo de traducir realmente la sintaxis es fácil. E incluso después de todo ese trabajo no tendrías código Java, tendrías algún tipo de monstruosidad que se ejecuta en la plataforma Java, pero que estaba estructurada como PHP en el interior.

Esta es la razón por la cual las únicas herramientas que vienen a la mente son la traducción del código para implementarlo, no para mantenerlo después. GWT de Google "compila" Java a JavaScript. El hiphop de Facebook compila PHP en C.

Joeri Sebrechts
fuente
Parece que alguien creó un traductor php a java y en realidad incorporó el binario PHP. De acuerdo, aunque no cambia su punto. runtimeconverter.com/single-post/2017/09/15/…
user1122069
20

Si tiene un formato intermedio, entonces podría implementar algo que traduzca un programa en el Idioma X a ese formato, y también desde ese formato al Idioma Y. Implemente esas conversiones para todos los idiomas que le interesen y ya está, ¿verdad?

Bien sabes que? Tal formato ya existe: ensamblaje. El compilador ya realiza la conversión del "lenguaje X al ensamblado" y desensambla a la conversión del "ensamblado al lenguaje Y".

Ahora, ensamblar no es un gran lenguaje para hacer la conversión inversa, pero MSIL no es tan malo. Descargue Reflector y verá que tiene opciones para desmontar un ensamblado .NET en varios idiomas diferentes (y los complementos proporcionan aún más). Por lo tanto, es bastante posible tomar un programa en C #, compilarlo en un archivo DLL (es decir, MSIL), luego usar el reflector para desarmarlo en VB, C ++ / CLI, F # y muchos otros. Por supuesto, todos los demás trabajos de conversión también. Tome un archivo F #, compílelo en un archivo DLL, use Reflector para convertirlo a C #.

Por supuesto, los dos grandes problemas que encontrarás son:

  1. El código es básicamente ilegible. MSIL (incluso con información de depuración) elimina mucha información de la fuente original, por lo que la versión traducida no tiene una fidelidad del 100% (en teoría, hacer una conversión C # -> MSIL-> C # debería devolverle el código original, pero no lo hará).
  2. Muchos lenguajes .NET tienen sus propias bibliotecas personalizadas (por ejemplo, la biblioteca de tiempo de ejecución VB, la biblioteca F #, etc.). Deberían incluirse (o convertirse) cuando realice su conversión también.

Realmente no hay nada para sortear el n. ° 2, pero probablemente pueda obtener el n. ° 1 con algunas anotaciones adicionales en el MSIL (a través de atributos, tal vez). Eso sería trabajo adicional, por supuesto.

Dean Harding
fuente
Muchos de los metadatos de la fuente original se incluyen en el MSIL (incluidos los comentarios XML y el método original, la propiedad y los nombres de los miembros), por lo que no creo que la conversión a C # sea tan ilegible como usted dice. Intente desarmar partes del marco .NET; Es muy legible. Por supuesto, la situación podría ser diferente para una conversión de F # a C #.
Robert Harvey
@Robert: los comentarios XML no están incluidos en el MSIL. Si observa, Microsoft.NET\Framework\v2.0.50727\enpor ejemplo, puede ver toda la documentación XML de las bibliotecas del sistema. Esto es lo que Reflector (et al) usa para mostrar los comentarios. La conversión no es ilegible, todo lo que decía es que no es 100% de fidelidad lo que se podría esperar de una traducción a nivel de fuente.
Dean Harding
2
Un desensamblador convierte el binario ejecutable de la máquina nuevamente en ensamblador para ese tipo de procesador en particular (No todo el mundo es un x86). Realmente te refieres a un descompilador para llevar el código compilado a la fuente. Esta es una tarea terriblemente difícil ya que cada compilador, de cada fabricante, en cada nivel de optimización convertirá las líneas de origen en una forma binaria de salida diferente.
uɐɪ
20

¿Es posible, al menos en teoría, escribir un traductor 100% correcto entre todos los idiomas? ¿Cuáles son los desafíos en la práctica?

  • Siempre es posible traducir de un lenguaje más estructurado a un lenguaje menos estructurado que todavía esté completo en Turing.
    • Este reclamo debe considerarse en un sentido estrictamente técnico: significa que el programa traducido producirá exactamente el mismo resultado cuando se ejecute.
    • No se implica nada acerca de la legibilidad del código traducido o la preservación de las estructuras originales del programa.
  • Es posible traducir de un lenguaje menos estructurado a un lenguaje más estructurado, pero el código traducido permanecerá en su forma menos estructurada.
rwong
fuente
1
Le diste al clavo. Intente leer el código que sale del backend C de LLVM. Es un código C técnicamente legal pero no es bonito (TM).
dsimcha
1
@dsimcha: aparte de la legibilidad, el backend de C hace que la salida sea mucho más fácil de leer que la depuración o el desmontaje. Estoy muy contento de que volvieron a traer ese backend, después de que se quedó sin mantenimiento por un tiempo.
JM Becker
10

¿Por qué quieres convertir un programa?

Ambos idiomas, el idioma de origen y el de destino se compilan en un código de máquina (virtual) de todos modos *, por lo que por razones técnicas no es necesario tener un compilador para otro lenguaje de alto nivel.

Los idiomas son para humanos. Entonces, el requisito implícito de su pregunta es: '¿por qué no hay un traductor que genere código legible '? , Y la respuesta sería (en mi humilde opinión): porque si hay dos idiomas que son suficientemente diferentes, las formas en que se escribe 'código legible' es diferente de una manera que no solo requeriría traducir los algoritmos, sino también tomar algoritmos diferentes.

Por ejemplo, compare una iteración típica en C y una en lisp. O pitones 'una mejor manera' con rubí idiomático.

Aquí, comienzan a aparecer los mismos problemas que tiene en idiomas reales, como si tradujera 'Está lloviendo gatos y perros' a algo con el significado de 'Está lloviendo como si fuera de cubos' al traducir del inglés al alemán, no puede traducir palabra por palabra más, pero hay que buscar el significado.

Y 'significado' no es un concepto fácil para trabajar.

*) bueno, hay coffeescript ...

keppla
fuente
1
Buena respuesta. Se podría agregar que si dos idiomas tuvieran exactamente el mismo conjunto de características y modismos, sería posible traducir un idioma a otro de manera bastante eficiente, pero la mayoría de los idiomas están diseñados con el propósito de admitir características y modismos que sus creadores sienten que no son adecuados compatible en otros idiomas . La traducción mecánica de código mantenible a veces es viable cuando las características y modismos en el idioma de destino son un superconjunto de aquellos en el idioma de origen, pero tales situaciones no son terriblemente comunes.
supercat
6

Es teóricamente posible pero sobre todo inútil. Casi cualquier combinación de lenguajes de origen y destino es posible, pero en la mayoría de los casos nadie querría mirar o usar el resultado.

Un buen número de compiladores apunta a C, simplemente porque los compiladores de C están disponibles para casi todas las plataformas existentes (y hay generadores de compiladores automáticos que le permitirán diseñar un procesador y generar automáticamente un compilador de C que apunte a su nuevo procesador). También hay, por supuesto, un buen número de implementaciones que se dirigen a los lenguajes utilizados por varias máquinas virtuales como .NET, JVM, C-- y LLVM.

Sin embargo, el punto clave es que en realidad solo es útil si el objetivo del tratamiento es básicamente un lenguaje ensamblador que solo se usa como un paso en el proceso de compilación. En particular, generalmente no desea que un programador normal lea o trabaje con ese resultado; Por lo general, no será muy legible.

Jerry Coffin
fuente
5

FWIW, hay un traductor de Java a D. Se llama TioPort y se usó en un intento bastante serio de portar SWT a D. El principal problema con el que se encontró fue que habría sido necesario portar porciones masivas de la biblioteca estándar de Java .

dsimcha
fuente
4

Si bien no es una traducción de código per se, el concepto de bancos de trabajo de idiomas muestra cómo se podría implementar algo similar a un traductor 100% correcto entre todos los idiomas.

En nuestro enfoque actual, el código fuente se almacena en un formato de texto. Durante la compilación, esos archivos de texto legibles por humanos se analizan en una representación de árbol de sintaxis abstracta, que a su vez se utiliza para generar código de bytes o código de máquina. Sin embargo, esta representación abstracta es temporal e interna para el compilador.

En el enfoque del entorno de trabajo del lenguaje, una representación de árbol de sintaxis abstracta similar es el artefacto almacenado permanente. Tanto el código de máquina como el código 'fuente' textual se generan en base a esta representación abstracta. Una de las consecuencias de tal método es que la representación abstracta del programa es en realidad independiente del lenguaje y puede usarse para generar código textual en cualquier lenguaje implementado. Lo que significa que una persona puede trabajar en diferentes aspectos del sistema libremente usando el lenguaje que considere más apropiado, o cada miembro del equipo puede trabajar en el proyecto compartido en el idioma con el que están más familiarizados.

Hasta donde yo sé, la tecnología aún está lejos de ser utilizable en el desarrollo convencional, sin embargo, hay varios grupos que trabajan en forma independiente. Es difícil saber si alguno de ellos cumplirá sus promesas, pero sería interesante ver que eso suceda.

scrwtp
fuente
¿Podría nombrar algunos de estos grupos?
Qwertie
4

No son algunos traductores automáticos. Si su objetivo es producir código compilable, en lugar de código legible, es bastante posible y, en ocasiones, útil, pero no con mucha frecuencia. Famosamente, el primer compilador de C ++ no era en realidad un compilador, sino que tradujo C ++ en una fuente de C (realmente complicada) que luego fue compilada por el compilador de C. Muchos compiladores pueden generar código de ensamblaje a pedido, pero en lugar de escupir texto de ensamblaje y luego traducirlo al código de máquina, normalmente pueden generar código de máquina directamente.

Dada una especificación completa del lenguaje A, en principio no es tan difícil escribir un programa que exprese sus directivas en algún idioma B. Pero, por lo general, cualquiera que se meta en problemas elegirá un nivel realmente bajo para "lenguaje B": código de máquina , o en la actualidad bytecode: Jython es una implementación de python que genera código de bytes java, que es interpretado por Java VM. ¡No hay necesidad de molestarse en escribir y compilar jerarquías de clases de Java!

alexis
fuente
3

Esto se hace todo el tiempo.

Cada compilador traduce el "lenguaje primario", como C ++, al lenguaje ensamblador nativo de la máquina o al código de bytes independiente de la arquitectura en el caso de los lenguajes interpretados.

Sin embargo, me imagino que no es de eso de lo que estás hablando. Probablemente desee un traductor que convierta C ++ a algo como Java o Python. Pero, ¿qué sentido tiene eso? En el mejor de los casos, el resultado final tendrá exactamente la misma eficiencia que la fuente original. (Prácticamente, será mucho peor).

Si solo desea traducir el código para poder leerlo como un idioma que entienda, dicho traductor tendría el efecto opuesto al deseado. Te quedará una gran cantidad de código críptico, poco intuitivo e ilegible.

Esto se debe a que solo las cosas más triviales se traducen directamente de un idioma a otro. A menudo, lo que es simple en un idioma requiere bibliotecas masivas para otro, o puede ser imposible por completo. Por lo tanto:

  1. Si el programa es trivial, puede obtener un resultado decente. Pero entonces, si es así de simple, ¿cuál es el punto de pasarlo por un traductor?
  2. Si el programa no es trivial, el código será de baja calidad.

Al final, la única forma de escribir un buen código es escribirlo realmente. Las computadoras simplemente no pueden, al menos no todavía, igualar a los humanos en cuestiones de legibilidad, mejores prácticas y soluciones elegantes.

En resumen, simplemente no vale la pena.

Maxpm
fuente
su analogía también se aplicaría a la compilación normal, y sabemos empíricamente que no. Las computadoras 'generan' (no escriben) código de buena calidad. Lo que a menudo hacen mal es la legibilidad / mantenibilidad. Si alguien necesitara tal proceso, lo que creo que la gente ocasionalmente necesita, ninguno de los dos problemas se detiene. Si lo son, bueno, obviamente, la traducción nunca fue importante originalmente.
JM Becker
1

No hay traductores de idiomas para lenguajes de programación porque los lenguajes de programación son increíblemente complejos. Si bien es hipotéticamente posible, existen muchos desafíos.

El primer desafío es simplemente en las prácticas aceptables del idioma. La conversión entre dos lenguajes orientados a objetos como Java y C ++ es increíblemente complejo, y ambos están basados ​​en C. El programa de traducción debería tener un conocimiento perfecto de las bibliotecas estándar para ambos idiomas y ser capaz de conocer las diferencias de comportamiento. Tendría que crear un diccionario masivo e incluso entonces, las diferencias en los estilos de programación de programador en programador significarían que tendría que adivinar cómo realizar algunos cambios.

Una vez que haya bajado la traducción de la sintaxis, debe descubrir cómo convertir una construcción en el primer idioma en una construcción en el segundo idioma. Esto está bien si vas a convertir un objeto en C ++ en un objeto en Java (comparativamente fácil), pero ¿qué haces con tus estructuras C ++? ¿O las funciones fuera de las clases de C ++? Decidir cómo manejar esto puede ser complicado, ya que puede dar lugar a otro problema, a saber, la creación de un objeto blob. El blob es un antipatrón que es bastante común.

Esta no es una lista completa de los problemas, pero esos son solo dos y son grandes. Uno de mis profesores mencionó que alguien convenció a su empleador de que podían hacer uno del código de máquina a C en los años 80, pero no funcionó en ese momento. Dudo que alguna vez haya uno que funcione completamente.

indyK1ng
fuente
Creo que no es necesario conocer las bibliotecas existentes, solo puede traducir las bibliotecas a medida que avanza (suponiendo que tengan fuentes disponibles).
serg
1
Eso en realidad aumenta la complejidad del segundo problema entonces. Y eso supone que tiene acceso al código fuente para traducirlo. De cualquier manera, todavía es bastante inviable.
indyK1ng
El punto +1 sobre libs es totalmente válido, y SIEMPRE hay libs.
Dan Rosenstark el
1

El punto de compilar es obtener algo útil para la computadora. es decir, algo que puede correr. ¿Por qué compilar a algo que incluso puede ser de un nivel superior al que escribió?

Me gusta más la estrategia de .NET. Compila todo en un lenguaje común. Esto ofrece la ventaja de que los idiomas pueden comunicarse sin necesidad de crear compiladores de idiomas cruzados (N ^ 2) -N.

Por ejemplo, si tuviera 10 lenguajes de programación, solo necesitaría escribir 10 compiladores bajo el modelo .NET y todos podrían comunicarse entre sí. Si hiciste todos los compiladores en varios idiomas posibles, necesitarías escribir 90 compiladores. Eso es mucho trabajo extra para poco beneficio.

mike30
fuente