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?
Respuestas:
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.
fuente
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:
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.
fuente
Microsoft.NET\Framework\v2.0.50727\en
por 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.fuente
¿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 ...
fuente
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.
fuente
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 .
fuente
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.
fuente
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!
fuente
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:
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.
fuente
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.
fuente
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.
fuente