viernes, 28 de febrero de 2014

Traductores: Ensambladores, compiladores e intérpretes

Un traductor es un programa que recibe como entrada código escrito en un cierto lenguaje y produce como salida código en otro lenguaje, generalmente el lenguaje de entrada es de más alto nivel que el de salida, por ejemplo, los traductores son los ensambladores y los compiladores.

Un traductor es un programa que toma el texto escrito en un lenguaje (el lenguaje fuente) y lo convierte en el texto equivalente en un segundo lenguaje (el lenguaje destino u objeto).

Cuando programamos en algún lenguajes de alto nivel, lo que estamos haciendo en realidad es el código fuente de ese programa, este código fuente debe ser traducido a lenguaje binario para que las instrucciones que contienen puedan ser entendidas y ejecutadas por la computadora.

Un ensamblador es un programa que traduce de un lenguaje ensamblador a lenguaje máquina, mientras que un compilador es un programa que traduce de un lenguaje de alto nivel a un lenguaje de bajo nivel o a lenguaje máquina.

Si la fuente es un lenguaje abstracto o de alto nivel y si el objetivo es un lenguaje de ensamble de bajo nivel o de máquina, el traductor es un compilador.

Los programas traductores de lenguajes son:
1. Compiladores
2. Interpretes

Debido la complejidad de la programación del lenguaje de máquina, en realidad son muy pocos los programas que se escriben con él. Sin embargo el lenguaje de maquina es el único lenguaje capaz de dar instrucciones directamente al CPU. Por lo tanto, toda instrucción de un programa de lenguaje que no sea de maquina tiene que traducirse al lenguaje de maquina antes de su ejecución. Esto se realiza mediante el software de sistemas que se llama traductor de lenguaje. Un traductor de lenguaje convierte un código fuente de un programador a su equivalente en lenguaje de máquina. El código de programa de nivel alto se conoce como el código fuente, mientras que el código de lenguaje de maquina se llama código objeto. 

Hay dos tipos de traductores de lenguajes: intérpretes y compiladores.

Para que un lenguaje de programación sea útil debe de tener un traductor es decir un programa que aceptan otros programas escritos en el lenguaje de cuestión y que, o los ejecuta directamente, o los transforma en una forma adecuada de su ejecución. Un traductor que produce un programa equivalente en una forma adecuada para su ejecución se conoce como compilador.

COMPILADOR

Los primeros compiladores se realizaron programándolos directamente en lenguaje máquina o en ensamblador. Actualmente existen herramientas que facilitan la tarea de escribir compiladores ó intérpretes informáticos. Estas herramientas permiten generar el esqueleto del analizador sintáctico a partir de una definición formal del lenguaje de partida, especificada normalmente mediante una gramática formal y barata, dejando únicamente al programador del compilador la tarea de programar las acciones semánticas asociadas.

Una vez que se dispone de un compilador, se pueden escribir nuevas versiones del compilador en el lenguaje que compila ese compilador.

Un compilador es un programa informático que traduce un programa escrito en un lenguaje de programación a otro lenguaje de programación, o también genera aplicaciones que sean directamente utilizables en un ordenador o computadora. Un compilador lee el código fuente creado en un determinado lenguaje de programación, lo interpreta, comprueba su sintaxis y traduce a lenguaje o código máquina toda la serie de instrucciones, generando el archivo ejecutable final.

Son programas que leen el código fuente y lo traducen o convierten a otro lenguaje, estos programas muestran los errores existentes en el código fuente.

ESTRUCTURA DE UN COMPILADOR

Se requiere un compilador para cada lenguaje de programación. Un compilador efectúa la traducción, no ejecuta el programa, una vez compilado el programa, el resultado en forma de programa objeto será directamente ejecutable.

La ejecución de un programa con compilador requiere de dos etapas:
Traducir el programa simbólico a código máquina
Ejecución y procesamiento de los datos.


El proceso de compilación considera las siguientes etapas:

  • Edición. Esta fase consiste en escribir el programa empleando algún lenguaje y un editor. Como resultado nos dará el código fuente de nuestro programa.

  • Compilación. En esta fase se traduce el código fuente obtenido en la fase anterior a código máquina. Si no se produce ningún error se obtiene el código objeto. En caso de errores el compilador los mostraría para ayudarnos a corregirlos y se procedería a su compilación de nuevo, una vez corregido.

  • Linkado. Esta fase consiste en unir el archivo generado en la fase dos con determinadas rutinas internas del lenguaje, obteniendo el programa ejecutable.



Existen dos tipos de linkados:

Linkado estático: Los binarios de las librerías se añaden a nuestros binarios compilados generando el archivo ejecutable.

Linkado dinámico: no se añaden las librerías a nuestro binario sino que hará que se carguen en memoria las librerías que en ese momento se necesiten.

Una vez traducido, compilado y linkado el archivo está listo para su ejecución donde también podrán surgir problemas y fallos, para los cuales tendríamos que volver a realizar todo el proceso anteriormente citado, de modo que puedan ser corregidos.

TIPOS DE COMPILADORES

Esta taxonomía de los tipos de compiladores no es excluyente, por lo que puede haber compiladores que se adscriban a varias categorías:

Compiladores cruzados: generan código para un sistema distinto del que están funcionando.

Compiladores optimizadores: realizan cambios en el código para mejorar su eficiencia, pero manteniendo la funcionalidad del programa original.

Compiladores de una sola pasada: generan el código máquina a partir de una única lectura del código fuente.

ESTRUCTURA DE UN COMPILADOR DE UNA SOLA PASADA

Compiladores de varias pasadas: necesitan leer el código fuente varias veces antes de poder producir el código máquina.

Compiladores JIT (Just In Time): forman parte de un intérprete y compilan partes del código según se necesitan.

FASES DE LA COMPILACIÓN

La compilación es el proceso de traducción de programas fuente o código fuente a programas objeto o código objeto.

Analizador léxico: también denominado scanner. Su función consiste básicamente en agrupar los caracteres del texto fuente en grupos con entidad propia denominados tokens, que son los identificadores, palabras reservadas, separadores. Los tokens reconocidos son la entrada a la siguiente fase, el analizador sintáctico.

Analizador sintáctico: se ocupa de analizar la sintaxis de las sentencias, de acuerdo con la descripción sintáctica reflejada en la gramática.

Analizador semántico: Se ocupa de analizar la semántica de las sentencias realizando una serie de consultas en unas tablas auxiliares denominadas tablas de símbolos.

TABLA DE SÍMBOLOS

Estructura de datos que contiene un registro por cada identificador, con los campos para los atributos: información sobre la memoria asignada, tipo, si es nombre de procedimiento (número, tipo y método de paso de cada argumento).

Permite encontrar rápidamente cada ID y almacenar o consultar datos de ese registro.

En el Análisis Léxico se detectan los ID y se introducen en la Tabla de Símbolos.

Las fases restantes introducen información sobre los ID y después la utilizan.

OPTIMIZACIÓN DE CÓDIGO

Trata de mejorar el código intermedio para que resulte un código de máquina más rápido de ejecutar.

Compiladores optimizadores: La fase de optimación ocupa una parte significativa del tiempo del compilador.

Hay optimaciones sencillas que mejoran el tiempo de ejecución del programa sin retardar mucho la compilación.

ANÁLISIS DEL FLUJO DE CONTROL.- Proceso que identifica los lazos dentro del grafo de flujo de un programa.

ANÁLISIS DEL FLUJO DE DATOS.- Proceso para recopilar información sobre el modo en que se utilizan las variables en un programa. Considera varios algoritmos para recopilar información, y el impacto de construcciones de lenguaje como los procedimientos y apuntadores.

TRANSFORMACIONES.- Mejoras que se realizan al código con el fin de obtener programas en lenguaje objeto eficientes.

GENERADOR DE CÓDIGO

Se ocupa de generar código objeto para una maquina, es decir, donde efectivamente se hace la traducción.

Existe una otra fase, opcional pero muy usada en los compiladores modernos, que es el optimizador de código, ocupándose de optimizar el tamaño y velocidad del código generado en la fase anterior.

Un compilador necesita guardar y usar la información de los objetos que va encontrando en el lenguaje fuente, como variables, etiquetas, declaraciones de tipos, etc. Esta información se va introduciendo en estructura de datos internos al compilador conocida con el nombre de tabla de símbolos.

El conjunto de procedimientos para el manejo de esta tabla, como introducir un nuevo símbolo, consultar la información de un símbolo, modificarla, borrarla, etc., es lo que se denomina control de las tablas de símbolos. En cuanto al tratamiento de errores es el conjunto de rutinas y actividades que tratan la identificación de un error, su posible tratamiento o recuperación y la emisión del mensaje correspondiente.

Hay que hacer notar la diferencia entre el BASIC interpretado y el compilado, que sería un buen ejemplo entre ambas técnicas de traducción. En el BASIC intérprete se interpreta cada una de las líneas del programa, con lo que se hace lenta la ejecución del programa; con el compilado se consigue un programa objeto que, una vez linkado, es un programa ejecutable globalmente. Todos los demás lenguajes citados tienen un traductor del tipo compilador.

INTÉRPRETES

Un programa intérprete o traductor, analiza directamente la descripción simbólica del programa fuente y realiza las instrucciones dadas.

Es un programa que traduce un lenguaje de alto nivel al lenguaje de máquina de una computadora, el programa siempre permanece en su forma original y traduce cuando está en la fase de ejecución instrucción por instrucción.

La interpretación es un proceso que consta de un paso, en donde tanto el programa como la entrada le son dados al intérprete y se obtiene de una salida.

El intérprete en los lenguajes de programación simula una máquina virtual, donde el lenguaje de máquina es similar al lenguaje fuente.

La ventaja del proceso interprete es que no necesita de dos fases para ejecutar el programa, sin embargo su inconveniente es que la velocidad de ejecución es más lenta ya que debe analizar e interpretar las instrucciones contenidas en el programa fuente.

Comparando su actuación con la de un ser humano, un compilador equivale a un traductor profesional que, a partir de un texto, prepara otro independiente traducido a otra lengua, mientras que un intérprete corresponde al intérprete humano, que traduce de viva voz las palabras que oye, sin dejar constancia por escrito.

En la actualidad, uno de los entornos más comunes de uso de los intérpretes informáticos es Internet, debido a la posibilidad que estos tienen de ejecutarse independientemente de la plataforma.

Traduce y ejecuta una línea del programa a la vez. Si hay error, detiene ejecución del programa. Programas más lentos pero más portables y flexibles. Los intérpretes realizan la traducción y ejecución de forma simultánea, es decir, un intérprete lee el código fuente y lo va ejecutando al mismo tiempo.

Las diferencias entre un compilador y un intérprete básicamente son:

Un programa compilado puede funcionar por si solo mientras que un código traducido por un intérprete no puede funcionar sin éste.

Un programa traducido por un intérprete puede ser ejecutado en cualquier máquina ya que, cada vez que se ejecuta el intérprete, tiene que compilarlo.

Un archivo compilado es mucho más rápido que uno interpretado.

El intérprete traduce una sentencia de programa a la vez, según se ejecuta el programa. 

Mostrara en la pantalla cualquier error que encuentre en la sentencia. Esta traducción línea por línea hace que los intérpretes sean ideales para quienes se hallan en el aprendizaje de la programación, pero hace más lento el proceso de ejecución.

Código fuente: Es un conjunto de instrucciones del programa que están escritas en un lenguaje de programación.

Lenguaje de maquina: Instrucciones nativas del CPU
Lenguaje de alto nivel: Más expresivo a nivel de aplicación.

ENSAMBLADORES

Los ensambladores son programas que procesan los enunciados del programa origen en lenguaje ensamblador y los traducen en archivos en lenguaje máquina que son ejecutados por un microprocesador o un microcontrolador. Los ensambladores permiten que los programas origen se escriban y se editen en una computadora para generar un código ejecutable en otra computadora. El archivo en lenguaje objeto ejecutable resultante se carga y se ejecuta en el sistema destino.

PROCESAMIENTO DE ENSAMBLADO

Este ensamblador es de dos pasadas.
Durante la primera pasada, el programa origen se lee para desarrollar la tabla de símbolos.
Durante la segunda pasada el archivo objeto se crea con referencia a la tabla desarrollada en la primera pasada.
Durante la segunda pasada se crea el listado del programa origen.

Cada enunciado origen se procesa completamente antes de que el enunciado siguiente se lea.

A medida que el enunciado se procesa el ensamblador examina los campos de etiqueta, de código de operación y de operandos.

La tabla de códigos de operación se revisa para encontrar un código operacional similar.

Durante el procesamiento de un mnemónico correspondiente a un código de operación normal, el código máquina normal se inserta en el archivo objetivo.

La acción buscada por una directriz del ensamblador ocurre durante el procesamiento de dicha directriz.

Cualquier error que detecta el ensamblador se muestra justamente antes de la línea que contiene dicho error.

Aún y cuando no se desee producir un listado origen, los errores se despliegan para indicar que el procesamiento de ensamblado no se llevó a cabo de manera normal.

LENGUAJE ENSAMBLADOR

El lenguaje simbólico que se utiliza para codificar los programas origen que se procesan por el ensamblador es llamado lenguaje ensamblador.

Este lenguaje es una colección de símbolos mnemónicos que representan: operaciones, nombres simbólicos, operadores y símbolos especiales.

El lenguaje ensamblador proporciona códigos de operación de los mnemónicos para todas las instrucciones de la máquina contenidas en la lista de instrucciones.

Además, el lenguaje ensamblador contiene mnemónicos directrices, los cuales especifican acciones auxiliares que se llevan a cabo por el ensamblador. Estas directrices no siempre son traducidas a lenguaje maquina.

LENGUAJE INTERPRETADO

Un lenguaje de programación es, por definición, diferente al lenguaje máquina. Por lo tanto, debe traducirse para que el procesador pueda comprenderlo. Un programa escrito en un lenguaje interpretado requiere de un programa auxiliar, que traduce los comandos de los programas según sea necesario.

LENGUAJE COMPILADO

Un programa escrito en un lenguaje "compilado" se traduce a través de un programa anexo llamado compilador que, a su vez, crea un nuevo archivo independiente que no necesita ningún otro programa para ejecutarse a sí mismo. Este archivo se llama ejecutable.

Un programa escrito en un lenguaje compilado posee la ventaja de no necesitar un programa anexo para ser ejecutado una vez que ha sido compilado. Además, como sólo es necesaria una traducción, la ejecución se vuelve más rápida.

Sin embargo, no es tan flexible como un programa escrito en lenguaje interpretado, ya que cada modificación del archivo fuente requiere de la compilación del programa para aplicar los cambios.

LENGUAJES INTERMEDIARIOS

Algunos lenguajes pertenecen a ambas categorías (LISP, Java, Python...) dado que el programa escrito en estos lenguajes puede, en ciertos casos, sufrir una fase de compilación intermediaria, en un archivo escrito en un lenguaje ininteligible y no ejecutable. Los applets Java, pequeños programas que a menudo se cargan en páginas Web, son archivos compilados que sólo pueden ejecutarse dentro de un navegador Web.

No hay comentarios:

Publicar un comentario