traductores de lenguajes de programación

Un traductor es cualquier programa que toma como entrada un texto escrito en un lenguaje, llamado fuente y da como salida otro texto en un lenguaje, denominado objeto.

Existen distintos tipos de traductores, entre ellos destacan:

Interpretes

Interpretes

Traduce a lenguaje máquina, cada línea del programa fuente y la ejecuta de inmediato.

Traducen en Lenguaje de Alto Nivel a Lenguaje Maquina, se encargan de traducir cada instrucción, una por una (o cada línea de instrucciones) contenida en un programa escrito en cualquier lenguaje de alto nivel a instrucciones en código binario, comprensible por las computadoras.

Los intérpretes no producen código objeto, por ello la ejecución de un programa requiere forzosamente del código fuente. Además, los programas en lenguaje interpretado se ejecutan con más lentitud que aquellos en lenguaje compilado.

Los intérpretes realizan la traducción y ejecución de forma simultanea, es decir, un intérprete lee el código fuente y lo va ejecutando al mismo tiempo.

Se pueden utilizar como alternativa a los compiladores para traducir lenguajes de alto nivel. En vez de traducir el programa fuente y grabar en forma permanente el código objeto que se produce durante la corrida de compilación para utilizarlo en una corrida de producción futura, el programador sólo carga el programa fuente en la computadora junto con los datos que se van a procesar. A continuación, un programa intérprete, almacenado en el sistema operativo del disco, o incluido de manera permanente dentro de la máquina, convierte cada proposición del programa fuente en lenguaje de máquina conforme vaya siendo necesario durante el proceso de los datos. No se graba el código objeto para utilizarlo posteriormente.

La siguiente vez que se utilice una instrucción, se le debe interpretar otra vez y traducir a lenguaje máquina. Por ejemplo, durante el procesamiento repetitivo de los pasos de un ciclo, cada instrucción del ciclo tendrá que volver a ser interpretado cada vez que se ejecute el ciclo, lo cual hace que el programa sea más lento en tiempo de ejecución (porque se va revisando el código en tiempo de ejecución) pero más rápido en tiempo de diseño (porque no se tiene que estar compilando a cada momento el código completo). El intérprete elimina la necesidad de realizar una corrida de compilación después de cada modificación del programa cuando se quiere agregar funciones o corregir errores; pero es obvio que un programa objeto compilado con antelación deberá ejecutarse con mucha mayor rapidez que uno que se debe interpretar a cada paso durante una corrida de producción.

En general, se puede decir que un lenguaje es interpretado si sus instrucciones se ejecutan secuencialmente a partir de código fuente. Para ejecutar el código de un lenguaje interpretado, necesitamos un intérprete de ese lenguaje. El intérprete irá recibiendo líneas de código que traducirá a lenguaje máquina para que se ejecute. A diferencia de los lenguajes compilados, no se produce un ejecutable. De este modo, de una plataforma a otra, sólo habrá que cambiar el intérprete, no el código.

La siguiente figura muestra el funcionamiento de un interprete.




Etapas del proceso de interpretación

A la hora de construir un intérprete es conveniente utilizar una Representación Interna (RI) del lenguaje fuente a analizar. De esta forma, la organización interna de la mayoría de los intérpretes se descompone en los módulos:

· Traductor a Representación Interna: Toma como entrada el código del programa P en Lenguaje Fuente, lo analiza y lo transforma a la representación interna correspondiente a dicho programa P.

· Representación Interna (P/RI): La representación interna debe ser consistente con el programa original. Entre los tipos de representación interna, los árboles sintácticos son los más utilizados y, si las características del lenguaje lo permiten, pueden utilizarse estructuras de pila para una mayor eficiencia.

· Tabla de símbolos: Durante el proceso de traducción, es conveniente ir creando una tabla con información relativa a los símbolos que aparecen. La información a almacenar en dicha tabla de símbolos depende de la complejidad del lenguaje fuente. Se pueden almacenar etiquetas para instrucciones de salto, información sobre identificadores (nombre, tipo, línea en la que aparecen, etc.) o cualquier otro tipo de información que se necesite en la etapa de evaluación.

· Evaluador de Representación Interna: A partir de la Representación Interna anterior y de los datos de entrada, se llevan a cabo las acciones indicadas para obtener los resultados. Durante el proceso de evaluación es necesario contemplar la aparición de errores

· Tratamiento de errores: Durante el proceso de evaluación pueden aparecer diversos errores como desbordamiento de la pila, divisiones por cero, etc. que el intérprete debe contemplar.

Ventajas de la utilización de intérpretes

En general, la utilización de compiladores permite construir programas más eficientes que los correspondientes interpretados. Esto es debido a que durante la ejecución de código compilado no es necesario realizar complejos análisis (ya se hicieron en tiempo de compilación), además, un buen compilador es capaz de detectar errores y optimizar el código generado.

Los intérpretes, por definición, realizan la fase de análisis y ejecución a la vez, lo cual imposibilita tales optimizaciones. Por esta razón, los sistemas interpretados suelen ser menos eficientes que los compilados. No obstante, los nuevos avances informáticos aumentan la velocidad de procesamiento y capacidad de memoria de los ordenadores. Actualmente, la eficiencia es un problema menos grave y muchas veces se prefieren sistemas que permitan un desarrollo rápido de aplicaciones que cumplan fielmente la tarea encomendada.

Tipos de intérpretes

  • Intérpretes puros

Son los que analizan y ejecutan sentencia a sentencia todo el programa fuente. Siguen el modelo de interpretación iterativa y, por tanto, se utilizan principalmente para lenguajes sencillos.

Los intérpretes puros se han venido utilizando desde la primera generación de ordenadores al permitir la ejecución de largos programas en ordenadores de memoria reducida, ya que sólo debían contener en memoria el intérprete y la sentencia a analizar y ejecutar en cada momento. El principal problema de este tipo de intérpretes es que si a mitad del programa fuente se producen errores, se debe de volver a comenzar el proceso.

  • Intérpretes avanzados

Incorporan un paso previo de análisis de todo el programa fuente. Generando posteriormente un lenguaje intermedio que es ejecutado por ellos mismos.

De esta forma en caso de errores sintácticos no pasan de la fase de análisis. Se utilizan para lenguajes más avanzados que los intérpretes puros, ya que permiten realizar un análisis más detallado del programa fuente (comprobación de tipos, optimización de instrucciones, etc.)

  • Intérpretes incrementales

Existen ciertos lenguajes que, por sus características, no se pueden compilar directamente. La razón es que pueden manejar objetos o funciones que no son conocidos en tiempo de compilación, ya que se crean dinámicamente en tiempo en ejecución. Entre estos lenguajes, pueden considerarse

Smalltalk, Lisp o Prolog. Con el propósito de obtener una mayor eficiencia que en la interpretación simple, se diseñan compiladores incrementales. La idea es compilar aquellas partes estáticas del programa en lenguaje fuente, marcando como dinámicas las que no puedan compilarse. Posteriormente, en tiempo de ejecución, el sistema podrá compilar algunas partes dinámicas o recompilar partes dinámicas que hayan sido modificadas. Estos sistemas no producen un código objeto independiente, sino que acompañan el sistema que permite compilar módulos en tiempo de ejecución (run time system) al código objeto generado.

Normalmente, los compiladores incrementales se utilizan en sistemas interactivos donde conviven módulos compilados con módulos modificables.

  • Evaluadores Parciales

La utilización de evaluadores parciales o especializadores surge al considerar que muchos programas contienen dos tipos de datos de entrada. Existen una serie de datos de entrada que son diferentes en cada ejecución mientras que otros datos no varían de una ejecución a otra. El primer conjunto, se conoce como datos de entrada dinámicos (se denotará como Din), mientras que el segundo conjunto, serían los datos de entrada estáticos (Est). Dado un programa P, el proceso de evaluación parcial consiste en construir otro programa especializado PEst para los datos estáticos de P. El programa PEst suele estar escrito en el mismo lenguaje fuente que P y se debe garantizar que cuando se le presenten los datos dinámicos produzca los mismos resultados que si se hubiesen presentado todos los datos al programa P original.

A continuación, un breve tutorial de como descargar e instalar el Interprete Python, además de como ejecutar programas sencillos usando esta herramienta :