¿Existen programas que puedan 'traducir' el código fuente entre dos idiomas (suponiendo que el traductor tenga acceso a las bibliotecas necesarias)?
Si los hay, ¿cómo funcionan (técnicas utilizadas, conocimiento requerido, etc.)? ¿Cómo se construirían de manera factible?
Si no lo son, ¿cuáles son las restricciones que impiden su desarrollo? ¿Es este un problema completo de IA (la traducción del lenguaje natural se enumera como una)?
EDITAR La conversión solo se espera, cuando el idioma tiene el mismo poder de expresión, puede resolver el mismo tipo de problemas y el código a convertir puede expresarse en el idioma de destino. (Por ejemplo, no se espera la conversión de un script de shell a MATLAB).
computability
programming-languages
compilers
Tobi Alafin
fuente
fuente
Respuestas:
TLDR; Esto es posible pero no práctico.
Esto termina siendo complicado, y es parte de por qué cosas como esta no terminan siendo utilizadas en la práctica.
Todos los compiladores son traductores. Definitivamente es posible traducir de un idioma a otro, y esto es literalmente todo lo que un compilador está haciendo. El lenguaje que un compilador escupe como salida es generalmente código de máquina o ensamblado, pero este es solo otro idioma, y hay compiladores (a veces llamados transpiladores o transcompiladores) que traducen entre dos idiomas . Por ejemplo, hay una gama de lenguajes de compilación a Javascript como PureScript, Elm, ClojureScript, etc.
Siempre es posible traducir entre dos idiomas completos de Turing. Ignorando cosas como llamadas a la biblioteca y FFI y otras partes prácticas desagradables que se interponen, eso es. Si un idioma es Turing completo, entonces tienes:
Entonces, para traducir del idioma A al idioma B, conviertes el código A en una máquina de Turing, luego conviertes esa máquina en código B.
Por supuesto, en la práctica, los bits prácticos se interponen en el camino, y esto también requiere que tenga las traducciones accesibles para usted. Existen básicamente para todos los idiomas, pero eso no significa que alguien se haya tomado el tiempo para escribirlos.
Hacer esta traducción eficientemente es difícil . Diferentes idiomas dan prioridad a diferentes cosas. Por ejemplo, si traduces de C a Python, probablemente tengas que terminar simulando la memoria de C como un diccionario de Python, para que puedas hacer aritmética de puntero. Habrá una sobrecarga asociada con esto, porque ahora no está accediendo a las instrucciones de memoria de metal desnudo.
Los diferentes idiomas tienen diferentes prioridades de rendimiento, por lo que algo que un idioma optimiza (o más bien, una implementación de un idioma optimiza) podría ser imposible de hacer rápidamente en otro idioma. La traducción de un idioma funcional con llamadas de cola adecuadas se ralentizará si la traduce a un idioma sin las llamadas de cola adecuadas.
Hacer esta traducción no hace que el código sea legible . Es fácil obtener un código en el lenguaje B que se comporta igual que el código del lenguaje A. Es difícil hacer que parezca un código que un humano habría escrito en B, por varias razones. A y B pueden tener diferentes herramientas de abstracción, y la computadora no tiene idea de qué hace que el código sea legible. Esto será particularmente cierto si terminas usando la traducción automática de Turing que describí anteriormente.
Esto plantea la pregunta: ¿cuál es el punto de tal traducción? Si todo lo que obtiene al final es un bloque de código lento e ilegible, ¿por qué no solo compilarlo en código de máquina y usar algún tipo de comunicación FFI o entre procesos para unir las piezas?
Hay algunas excepciones a esto. A veces necesitas cosas en un idioma determinado (como JavaScript). A veces el lenguaje es similar, y una traducción sensata es fácil. A veces, un idioma no está destinado a ejecutarse, sino a extraer su código en otro idioma (como Coq).
Pero en general, no es algo muy práctico.
fuente
Hay tales programas. Por ejemplo, los traductores de Lisp a Fortran, que fueron ampliamente utilizados en su momento. Los compiladores de Sole Lisp no compilan Lisp directamente, sino que generan código C que luego es compilado por un compilador de C normal. Otro ejemplo sería Vala que no se compila directamente, sino que primero se traduce a C ++ antes de compilar el código de C ++. Qt está escrito en MOC, un lenguaje que se traduce a C ++ para compilarlo (pero como MOC es solo C ++ con algunos comandos adicionales, se puede argumentar si realmente se va a llamar un "nuevo lenguaje"), y antes de eso eran compiladores de C ++ había traductores de C ++ a C. Y algunos proyectos se escribieron en Pascal y luego se tradujeron a C. Además, el clang y Java tienden a ser algo así, ya que traducen código C ++ y Java a algún lenguaje intermedio que luego se puede procesar más.
Lo que no puede esperar de la salida de un traductor de idiomas es que el resultado tenga sentido para un lector humano: la tarea del programa es escribir código que resulte en un programa que haga lo mismo que el código original (que en mi experiencia podría o podría no funciona, dependiendo de las características del idioma y las bibliotecas externas que estaba usando). Pero como no conoce el propósito de esta tarea para el resto del significado del programa, podría perderse en gran medida.
fuente
No es una respuesta directa, pero hay una herramienta llamada ILSpy , que fue escrita para .Net Framework, y le permite descompilar un ensamblado .Net en C # o VB.Net.
Si no está familiarizado con la naturaleza de .Net, puede escribir código .Net en muchos idiomas, pero principalmente C # o VB.Net. Cuando el compilador compila la aplicación, traduce el código a un código de "lenguaje intermedio" (o IL para abreviar). Este código luego se compila en binarios .Net.
Dado que las aplicaciones .Net son archivos binarios compilados a partir del código IL, ILSpy puede tomar la aplicación .Net, revertirla al código IL y, posteriormente, llevarla un paso más allá y volverla a C # o VB.Net.
Con esta herramienta, todo lo que tiene que hacer es compilar una aplicación, y luego puede examinar los archivos compilados como código IL, C # o VB.Net. Para ser claros, no importa en qué idioma se escribió inicialmente el código. Siempre que el binario sea un ensamblado .Net, puede realizar ingeniería inversa de los archivos compilados y generar el contenido como cualquiera de estos tres idiomas.
Sé que esto no es exactamente un compilador, pero es una herramienta que ofrece un resultado final similar a lo que está buscando y, de hecho, lo he usado para "traducir" proyectos de VB.Net en algo un poco más familiar para mí-- C #.
fuente
Para su caso de uso (basado en comentarios), parece que SWIG podría ser útil.
fuente
Recuerdo el venerable f2c , que hace la traducción de fuente a fuente de Fortran 77 a C.
Fue (a veces es ...) utilizado principalmente para traducir código numérico de hace décadas sin tener que integrar un compilador fortran a su cadena de herramientas.
fuente
La teoría que le dice que tales programas existen, en principio, se llama numeración admisible . Podemos demostrar que existen compiladores computables entre dos numeraciones, y cada formalismo completo de Turing (o lenguaje de programación) es, en esencia, uno.
fuente