My signature
Principia Diseño de Compiladores

Solo una barra

CAPITULO I


I.- Introducción al Diseño de Compiladores y Lenguajes de Cómputo

La computadora es la máquina más versátil concebida por el hombre. Aunque inicialmente es construida como un mecanismo de cálculo de prestaciones superiores a los primeros dispositivos mecánicos y electromecánicos, con el paso del tiempo se le incorporaron capacidades para la realización de operaciones lógicas y para la manipulación de datos no numéricos. Un largo proceso evolutivo ha llevado a este dispositivo calculador de la aritmética de cifras a la generación de información, teniendo como meta inmediata la manipulación del conocimiento y como objetivo futuro la generación de conciencia.

Las actuales computadoras son capaces de realizar los más complejos cálculos aritméticos, lógicos y simbólicos, de emular los más elaborados mecanismos (incluyendo a otros computadores), de simular eventos naturales y de crear mundos virtuales. Las crecientes capacidades con que se presentan generación tras generación acercan a los nuevos computadores cada vez más a la realización de tareas mucho más complejas y que se antojan imposibles, como pueden ser la emulación de la mente y el pensamiento.

Todo esto se sustenta, por supuesto, en la electrónica y en la capacidad de programación del computador. Sabemos que la electrónica del computador se denomina digital y que funciona con base en valores discretos. Sabemos que es a través de códigos y estrategias de representación de datos como podemos alimentar al computador con nuestras ideas y las expresiones con que identificamos a los objetos en nuestro mundo análogo y tridimensional. También sabemos que mediante reglas de operación perfectamente definidas podemos instruir al computador en la manipulación de dichos datos que llevarán a la generación de otros y a la obtención de información en la resolución de problemas. La forma de expresar dicha instrucción y la manera de llevar a cabo su traducción a lo que el computador es realmente capaz de procesar son el tema de estas páginas.


1. La aplicación y utilización de los conocimientos, técnicas y herramientas usadas en el diseño de compiladores y lenguajes de cómputo.

El tema del diseño de compiladores y lenguajes en la ciencia de la computación es usualmente visto como uno de los más complejos, áridos y abstractos. Adicionalmente suele considerarse que estos temas no dejan de ser de un interés meramente académico, a menos que se trate de una enorme compañía de software dedicada a la creación de herramientas de desarrollo. Tales creencias han dado lugar a una enorme variedad de mitos, algunos de estos por ejemplo son:

Aunque al final de esta sección expondremos el porqué las aseveraciones anteriores deben ser consideradas como falsas o imprecisas, dejaremos que primero el lector aprecie por sí mismo las implicaciones del conocimiento que está por recibir. Esperamos que el material aquí expuesto le permita obtener una mejor apreciación tanto sobre la teoría de compiladores y lenguajes como de su didáctica y utilización.

1.1. Aspectos comerciales y de desarrollo de la ingeniería de software.

Existe una gran variedad de lenguajes de programación. Cada uno retrata una corriente en la conceptualización de datos, información y procesos. Para cada uno de estos lenguajes existen una o diversas implementaciones, así como herramientas de desarrollo adicionales.

Algunos de estos productos son freeware, otros son shareware y algunos otros más son productos de marca. Los dos primeros resultan, respectivamente, gratis y baratos mientras que los últimos son un recurso caro, tanto que inclusive puede superar el costo de muchos otros recursos, como puede ser el del hardware.

Sea cual fuere el tipo de herramienta que usemos para desarrollar bajo un determinado lenguaje de programación, tendremos dos tipos de costos a considerar como resultado de nuestra decisión. El costo directo de estos productos, que incluye:

Licencias. El mayor de todos los costos son las licencias de desarrollo. Es a través de éste como el fabricante del software recupera la inversión hecha en investigación y desarrollo.

Capacitación. El uso de un nuevo lenguaje o software de desarrollo puede requerir de instrucción especializada para su adecuada utilización.

Documentación. La adquisición de material bibliográfico y manuales que incrementen el conocimiento sobre la herramienta.

Soporte técnico. Si la herramienta o el ciclo de desarrollo que ésta impone es complejo, o si se trata de una nueva herramienta, paradigama o lenguaje de programación, se requiere contar con la asesoría especializada del fabricante o de un desarrollador con experiencia para la resolución de dudas o problemas particulares.

Contratos de actualización. El avance en el desarrollo de la computación e informática obliga a que se compren nuevas versiones del producto o que se cuente con un contrato que garantice su actualización.

Adicionalmente, pero definitivamente influenciado por la adquisición de un software de desarrollo, tenemos costos indirectos:

Curvas de aprendizaje. Sobre todo si se trata de algo nuevo, existe un periodo de tiempo que debe pasar antes de que el desarrollador se familiarice y adquiera experiencia con un lenguaje o herramienta de programación. Esto no debe confundirse con la capacitación; la Curva de Aprendizaje se refiere a todo el tiempo que el programador debe invertir para dominar la nueva herramienta a usar y que es un periodo en el cual no es productivo (se encuentra en capacitación o en el análisis de documentación).

Compra o actualización de equipo. Conforme el software de desarrollo se hace más complejo se requiere que se cuente con determinados requerimientos mínimos de hardware. Estos serán más elevados conforme el software de desarrollo libere al programador de más y más tareas.

Distribución de desarrollos. Esto es algo muy difíl de cuantificar y es lo que más repercute para poder obtener un valor de retorno sobre la inversión en la adquisición de un software de desarrollo. Ciertos productos requieren que se distribuyan bibliotecas, intérpretes o elementos para que el producto final pueda trabajar. Esto y el pago de regalías es algo que no siempre se considera.

Dependencias. Una plataforma de desarrollo creará un vinculo de negocio con el proveedor o el equipo usado.

Limitaciones. Un lenguaje o herramienta de desarrollo imponen ciertas reglas de funcionamiento. La organización debe acoplarse a éstas de lo contrario se encontrará subutilizando un producto o forzando una forma de diseño o desarrollo que a la larga creará más problemas que los que soluciona.

Como podemos ver la selección de una herramienta de desarrollo tiene diversas implicaciones y de manera genérica ya se ha presentado lo que esto representa para nuestros recursos económicos, de equipo y personal. Ahora habría que preguntarse qué es lo que en un momento dado puede inclinarnos a elegir una herramienta haciendo caso omiso de las implicaciones ya mencionadas. La respuesta a esto es simple: publicidad y desconocimiento.

La publicidad juega un papel importante en nuestro mundo. Una hábil campaña publicitaria hará que se venda cualquier producto, lo necesite o no el consumidor, sea de alta o baja calidad. Desafortunadamente, la publicidad puede exagerar la verdad así como también puede ocultarla. Si el que está a cargo de la decisión de compra no posee los conocimientos necesarios para saber que es verdad, que es una exageración y que es una mentira, entonces fácilmente será influenciado por las cifras, colores, propaganda y demás elementos decorativos entorno al producto que esté evaluando. Es aquí donde el conocimiento cumple su cometido y permite develar aquello que es cierto de lo que es sólo parte de un arreglo mercadotécnico para centrar la atención del comprador en ciertos elementos del producto.

Por ejemplo, muchas herramientas de desarrollo o de depuración (debuggers) son usadas como principal elemento de venta. Sabiendo que la corrección de un programa en desarrollo o ya hecho es una de las actividades más demandantes en tiempo, el vendedor tratará de hacer ver a su producto como la solución final o universal. Algunas veces argumentará que inclusive es capaz de descompilar. La teoría atrás del diseño de un compilador permite saber que una herramienta de descompilación (universal o particular) o de depuración cuya entrada es código máquina puro es imposible de construir. Claro que es posible tener un ambiente de desarrollo con capacidades de depuración. Las estrategias generalmente consisten en generar código ejecutable con información adicional para labores de depuración, puede ser pseudo-compilado o inclusive ser interpretado. Un programa ejecutable únicamente podrá ser descompilable totalmente si este es generado con información de depuración y referencia al código fuente. Esto podría parecer algo deseable y que no trae consigo mayores complicaciones al producto final. Sin embargo, si esta característica no es deshabilitada, el resultado puede ser un código enorme, lento y demandante de recursos.

Se piensa que los compiladores y herramientas de desarrollo comerciales están diseñados para brindar el mayor control en la generación de código y para su depuración. Muchas veces no es así, encontrando que existen muchas herramientas de desarrollo que son distribuidas bajo licencias shareware o freeware con capacidades comparables, mejores o únicas a productos de marca. Cabe preguntarse entonces si el valor de un producto o el respaldo ofrecido puede justificar el precio solicitado. Quién esté a cargo de la selección del lenguaje de programación a usar y de las de herramientas necesarias para su manejo es el único que podrá responder a esta pregunta. Su respuesta será más acertada cuando se comparen los requerimientos del proyecto y los recursos disponibles sobre la base de un conocimiento formal sobre compiladores y lenguajes de programación; por ejemplo, poder determinar si lo que se requiere es contar con herramientas con facilidades para la optimización de código en tiempo de ejecución o en su tamaño, características mutuamente excluyentes en muchas ocasiones.

Mayores alternativas en la generación de los programas proporcionarán una mayor flexibilidad para su adaptación, distribución, y generación pero también crearán un mayor número de escenarios que deberán tenerse presentes para la integración de las aplicaciones. Algo más a tener en consideración es tanto el lenguaje a utilizar como la correspondiente herramienta. Existe un creciente número de lenguajes de programación. Cada uno refleja un paradigma de desarrollo diferente, las implicaciones de éste pueden ser las de mayor peso en la selección de la herramienta, pero la naturaleza misma de la herramienta deben ser tomadas en cuenta. El siguiente cuadro ilustra esto.


Lenguaje Modelo Características
C, C++, Fortran, COBOL, Pascal Compilado Sintaxis específica para tipos de datos. Ideal para el desarrollo de programas veloces o de tamaño reducido. Permiten la explotación de instrucciones especiales del microprocesador. Mayor seguridad para evitar alteración o robo de código fuente.
Java Pseudocompilado Transportabilidad absoluta. Requiere de una máquina virtual para ser ejecutado. Mejor desempeño que un programa interpretado pero más lento que uno compilado. Lenguajes de sintaxis rigurosa.
AWK, Basic, SQL, Lisp, Forth Interpretado Requiere del intérprete para su ejecución. Desempeño lento. Ideal para desarrollos rápidos (prototipos), operaciones no planeadas y programas pequeños y simples. Lenguajes de sintaxis más relajadas y mayor libertad para la conversión de datos.

Tabla 1.- Los tres modelos de ejecución de código.

Finalmente, y también digno de consideración es si los programas requieren de módulos de run-time, librerías o si son autocontenidos. Tan importante es conocer como será generado el código como el saber como será ejecutado. No sólo por cuestiones de licencias (número de usuarios o distribuciones) o de recursos (número de conexiones, memoria, espacio en disco) sino también por lo que implica el control y liberación de versiones, tiempo de distribución, dependencias e impacto a otros programas, y el asegurar la integridad de datos y sistemas.

Como puede verse, el profesional a cargo de la selección de una herramienta de desarrollo requiere mayores conocimientos que sólo "estar al día" para sopesar las distintas alternativas en la selección de la herramienta, las diversas formas de llevar a cabo el desarrollo de su proyecto (de manera general o con una herramienta específica), y tener el suficiente criterio para saber si las recomendaciones que reciba son verdaderas o producto de una campaña mercadotécnica. Por ejemplo, es posible que por seguridad o por rendimiento, un compilador sea la mejor opción a tomar pero también es cierto que muchos lenguajes sólo funcionan en versiones interpretadas. Desechar las facilidades que brinda un lenguaje sólo por su forma de ejecución puede no ser lo más acertado. Un lenguaje interpretado puede ser un buen candidato cuando se tienen previstas actividades que deberán ser hechas rápidamente o de forma únicas (formato de archivos, manipulación de datos, mantenimiento). Bajo estas circustancias conviene contar con herramientas que permitan la elaboración rápida de programas, carcaterística de los lenguajes interpretados.


1.2. La formación académica y de investigación.

El profesional de la informática puede no necesariamente enfrentarse al reto de desarrollar un intérprete o compilador (mas no está exento de éste) pero tarde o temprano tendrá que elegir alguna herramienta de desarrollo o lenguaje de programación, y conocer las bases de su funcionamiento le será de mucha ayuda para tomar la mejor decisión. Por su parte, para los estudiantes de la ciencia de la computación es un reto que invariablemente deben afrontar; lo mismo que los investigadores que buscan mejores compiladores o nuevos paradigams de programación y que será la forma en la que validarán o sustentarán sus resultados.

Adicionalmente, puede resultar de sumo interés los beneficios derivados de tomar una materia dedicada al diseño de compiladores. En esta no sólo se adquieren conocimientos que encuentran aplicación en otras áreas sino también es la oportunidad en la que pueden aplicarse los recibidos en cursos anteriores. Beneficios y oportunidades son enlistadas en la siguiente tabla:


Área/Materia Oportunidad
Programación de bajo nivel Lograr un dominio del la programación en lenguaje ensamblador y lenguaje máquina.
Ingeniería de software Aplicación de técnicas y conceptos en el desarrollo de un producto complejo.
Estructura de datos Utilización de diversas estructuras de datos en el desarrollo de los componentes del compilador o intérprete.
Teoría de Autómatas Aplicación práctica de ténicas formales en el desarrollo de los componentes de análisis del compilador o intérprete y en el diseño de lenguajes para sistemas de cómputo.
Teoría de la Computación Utilización de técnicas y conocimiento con propósitos analíticos.
Área/Materia Beneficios
Lenguajes de Programación Desarrollo e implementación de lenguajes de programación, consulta, de definición y de propósito específico. Consideraciones para los principios de desarrollo y construcción de herramientas que permitirán su materialización, incluyendo aquellos incrustados en aplicaciones.
Inteligencia Artificial Bases para el desarrollo de herramientas de análisis y procesamiento de lenguaje natural, traducción automatizada.
Arquitectura de Máquinas Conocimiento más preciso del funcionamiento del computador y los medios o mecanismos necesarios para su programación.
Sistemas Operativos Desarrollo de interfaces de control y usuario final. Desarrollo de intérpretes de comandos.
Diseño de Interfaces Hombre-Máquina Desarrollo de interfaces orientadas a comandos y caracter mejor diseñadas. Reconocimiento de voz y escritura.
Programación de Sistemas Panorama más completo sobre las herramientas a utilizar o desarrollar (e.g. analizadores de código y depuradores).
Administración de Proyectos Informáticos Selección de herramientas, evaluación de costos y beneficios, logistica y coordinación de recursos.

Tabla 2.- Ventajas y beneficios derivados del estudio de la materia de compiladores.

Bajo el entorno educativo es posible que la herramienta de desarrollo a usar sea indistinta (siempre y cuando esta no sea un objetivo del propio curso); sin embargo ésta adquirirá otro valor si se considera que en el ámbito profesional es de esperarse que las empresas requieran de profesionistas familiarizados con las herramientas estándar o en boga en la industria del software. El proporcionar dicha preparación o familiaridad en la preparación escolar es algo que dará ventajas a todo egresado en el competido mercado laboral. Claro que esta familiaridad trae consigo asociada un enorme costo y seguramente los costosos paquetes comerciales estén fuera del presupuesto de una institución educativa. Debe tener presente que los programas freeware o shareware siempre serán una opción y no deben ser menospreciados por su naturaleza de bajo costo, muchos de ellos pueden exhibir características similares a las comerciales e inclusive superiores.


1.3. Revalorización.

Como puede verse en los dos apartados anteriores, el profesional a cargo de la selección de los recursos y el establecimiento de las directrices tecnológicas para su grupo de trabajo u organización requiere de los conocimientos necesarios que le ayuden a evaluar alternativas, establecer guías, consolidar criterios y tomar las decisiones necesarias para sacar adelante un proyecto fijando los cimientos de los que vienen en camino. Para el investigador, académico y estudiante ofrece tanto el medio para hacerse de un sinnúmero de herramientas y conocimientos a usar en la solución de otros problemas como el conducto para aplicar otros previamente adquiridos y apreciar su importancia.

Es cierto que en nuestro país gran parte de las actividades de desarrollo de sistemas e informática están dedicadas al soporte de las actividades empresariales, que son en su gran mayoría labores administrativas y de control (nóminas, finanzas, contabilidad, inventarios, control y registro de personal, administración de clientes, etcétera). Esto hace del mercado de desarrollo de aplicaciones administrativas algo muy lucrativo que da la oportunidad de negocio para muchas empresas grandes y pequeñas. Con todo y esto, y aun cuando el costo es mayor, muchas organizaciones prefieren adquirir aplicaciones desarrolladas (inclusive por compañías extranjeras y aunque están diseñadas para realizar el trabajo bajo un marco económico, organizacional y legal muy diferente a las regulaciones y formas de trabajar en nuestro país).

Sin importar si el software es desarrollado o comprado, éste requerirá mantenimento, lo que presupone el uso de una herramienta de programación (no necesariamente la misma usada en su construcción). Curiosamente el desarrollo de este tipo de herramientas no se lleva a cabo en nuestro país. Ya sea por ser vista como un área de negocio limitada o por considerarse algo demasiado complejo; lo cierto es que todas las herramientas de programación y desarrollo de sistemas de información utilizadas en nuestro país son de procedencia extranjera.

Este es un punto que debe revalorarse seriamente. En la actualidad el desarrollo de compiladores e intérpretes es algo muy lucrativo. No sólo por los nuevos paradigmas de programación que pudieran surgir sino también por las tecnologías alrededor de HTML y XML, interfaces de usuario para todo tipo de software aplicativo, y herramientas de desarrollo para todo tipo de dispositivos programables.

Considerando todo lo ya expuesto, podemos decir:

1.4. Requisitos.

Finalmente, es de esperarse que en este punto muchos se pregunten qué es lo que se requiere para cursar un curso de esta naturaleza. En esencia, los requisitos a cubrir por toda persona interesada en el diseño y construcción de un compilador no diferen mucho de lo que se enlistó en las oportunidades de aplicación de conocimientos. La siguente tabala enlista los requisitos a cubrir y su justificación.


Requisito Justificación
Programación en lenguaje ensamblador El domino de la programación de bajo nivel, ya sea en lenguaje máquina o ensamblador, es algo que no puede evitarse. La materialización del compilador depende de esto. Podemos decir que una tercera parte del proyecto depende de esto.
Estructura de datos Se requiere un uso intensivo y extensivo de diversas estructuras de datos para construir los diversos elementos de análisis y síntesis del compilador.
Teoría de autómatas, lenguajes y computación Junto con las estructuras de datos, el conocimiento formal proporcionado en la teoría de autómatas, lenguajes, y computación forman una tercera parte de lo que se requiere para la materialización de un intérprete o compilador. Este conocimiento también es requerido para la especificación y diseño de un lenguaje de programación.
Lenguajes de Programación y programación usando un lenguaje de nivel intermedio o alto La última tercera parte del conocimiento básico solicitado reside en el conocimiento y habilidad de programación y en el conocimiento de como esto se puedo lograr usando diversos paradigmas e implementaciones.
Arquitectura de computadoras Por supuesto, dada la necesidad de conocer la programación en ensamblador, un conocimiento de la arquitectura y funcionamiento de un computador es necesario.
Sistemas operativos y programación de sistemas. Conocer como es que la computadora administra sus recursos y como puede lograrse interactuar con dicha administración es algo requerido.

Tabla 3.- Requisitos para el estudio de la materia de compiladores.

2. Lenguajes en computación e informática.

Aunque a lo largo de este primer capítulo hemos hecho referencia a los lenguajes de programación esto no quiere decir que el conocimiento, técnicas y herramientas que se discuten a lo largo de este curso sean para el exclusivo manejo y procesamiento de éstos. Los lenguajes de programación son únicamente una de las distintas clases formadas por los diversos tipos de lenguajes disponibles en el ámbito de la informática y computación. Sin importar su propósito, todo lo que aquí se mencione puede ser aplicado para el reconocimiento y procesamiento de cualquiera de estos lenguajes.

Todos los lenguajes pueden ser clasificados bajo diversos esquemas, principalmente por su proósito y naturaleza de funcionammiento. Sin embargo, antes de esto es necesario establecer una distinción entre todos estos lenguajes destinados a usarse en la computadora. Lo primero que procede es identificar el propósito por el que fueron creados. La siguiente tabla proporciona un excelente panorama al respecto.

Tipo de Lenguaje Descripción
Lenguajes de especificación. En esta categoría quedan englobados todos aquellos metalenguajes, formalismos y especificaciones usados para la descripción de otros lenguajes, así como hardware y software. Comunmente este tipo de lenguajes no son usados directamente en la computadora, aunque en algunos casos existe una correlación directa o cercana a la forma como ciertos dispositivos electrónicos son programados. Por lo general este tipo de especificaciones se utilizan como un estándar o formalismo para la descripción de otros lenguajes, técnicas de diagramación o simbolismos que son usados con un computador o dispositivo programable. Sin embargo, dada su estructura y regularidad, es perfectamente factible su uso directo en el computador.
Lenguajes de presentación y formato de datos. A esta categoría pertenecen todos aquellos lenguajes que son usados para el despliegue de datos en pantalla o medios impresos (razón por la que muchas veces son llamados lenguajes gráficos) a través de software o hardware especializado. La mejor forma de ejemplificar esta descripción es mediante la enumeración de algunos de los lenguajes que perteneces a ésta:
  • PCL. Printer Control Language. El lenguaje de descripción de páginas para las impresoras HP LaserJet y se ha vuelto un standard de facto entre dispositivos similares. PCL Level 5, introducido en 1990 con la LaserJet III dio soporte a las fuentes escalables Intellifont de Compugraphic. En 1996, con la LaserJet 5, PCL Level 6 redujo la cantidad de información que debe ser enviada a la impresora en comandos y gráficos.
  • HTML. Hyper Text Markup Language. Lenguaje para la especificación de como una página web debe ser mostrada por un navegador así como la información que algunos de los elementos desplegados deben contener para permitir su enlace con otras páginas.
  • PostScript. Un lenguaje descriptivo de páginas (PDL, Page Description Language) desarrollado por Adobe y que se ha vuelto el estándar de facto en el mercado de impresión y composición gráfica. Los comandos PostScript no controlan directamente a la impresora, estos son instrucciones ASCII que son traducidas a los comandos internos de la impresora por un intérprete interconstruido en ésta, incluyendo el escalamiento de fuentes tipográficas. PostScript Level 2 mantiene compatibilidad con el PostScript original e incorpora compresión de datos y mejoras para el manejo del color. PostScript Level 3 agregó muchas otras mejoras como fuentes nativas y la habilidad de soporte directo a HTML, PDF, GIF y JPEG. EPS (Encapsulated PostScript) es un subcanjunto de PostScript usado para el intercambio de imágenes gráficas simples en el formato PostScript.
Lenguajes de definición de datos. Data Definition Language es como se llama al subconjunto de algunos lenguajes o a ciertos lenguajes que están dedicados a la descripción de datos o estructuras dedicadas a contener datos. Existen dos ejemplos perfectos para ilustrar esto. El primero es el eXtensible Markup Language (XML), dedicado a la descripción de documentos y la información que éstos contendrán. Aunque para muchos el XML es un metalenguaje, a este no lo hemos clasificado en nuestra primera categoría porque aun el XML es descrito a travé de una especificación de orden superior. El segundo es el subconjunto de elementos sintácticos de las diversas implementaciones SQL que son empleadas en la construcción de tablas y la especificación de las características de cada una de las columnas.
Lenguajes de programación Todos aquellos lenguajes de propósito general. Estos proveen soluciones para un amplio margen de problemas de un área o varias áreas.
Lenguajes de propósito especial También llamados Lenguajes de Dominio Específico, Micro Lenguajes, o Lenguajes Pequeños son en esencia lenguajes de programación restringidos a un problema o procesamiento específico (muchas veces relacionado con la arquitectura de computador). Mientras que los lenguajes de programación genéricos pueden ser aplicados a cualquier tipo de problema, los lenguajes de tipo especializado (como lenguaje de programación o como lenguaje de espeficicación ejecutable) a través de la adecuada notación, declaración, abstracción, y un poder de expresión específicamente enfocado, están restringidos al dominio de un problema en particular.

Tabla 4.- Clasificación de los lenguajes por su uso.

Tanto los lenguajes de especificación, de presentación y de definición requieren del mismo procesamiento que cualquier otro para su reconocimiento, aunque éstos no requieren generalmente de una etapa de generación de código o de interpretación como los de programación o de propósito especial. Siendo estos dos tipos los de mayor interés para nosotros por la etapa de ejecución requerida por parte del computador nos centraremos ahora en la identificación de las diversas clasificaciones y modelos de programación entorno a éstos.

Primero, independientemente de si se trata de un lenguaje de propósito general o específico es importante entender lo que es un lenguaje de programación. Debemos entender como lenguaje de programación a todo conjunto de reglas y elementos gramaticales de los que un programador dispone para escribir el conjunto de instrucciones o indicaciones necesarias para la realización de una labor específica en la resolución de un problema.

Un primer esquema de clasificación es la evolución natural que estos han tenido a lo largo del tiempo. Es importante mencionar que los lenguajes de programación no han existido desde el primer instante en que existió un computador. Su aparición fue en realidad mucho posterior.

¿Cómo se llevaba a cabo la programación de los primeros computadores si es que no había lenguajes para tal efecto? Los primeros computadores se programaban en realidad recableándolos. Esto prácticamente equivalía a reconstruir todo el computador cuando se requería de un nuevo programa. La tarea era simplificada gracias a un panel de contactos (muy similar al de los primeros conmutadores telefónicos que eran atendidos por operadoras, y que hoy en día sólo llegamos a ver en viajes películas en blanco y negro) con el que era posible enlazar circuitos para crear secciones dedicadas a una actividad específicas. La programación del computador se llevaba a cabo, literalmente, reconstruyéndolo.

Fig 1.- La ENIAC.

Mientras que el recablear al computador establecía una clara distinción entre los datos (representados por los estados o señales eléctricas que serían mantenidas por los relevadores o a través de los bulbos que conformaban al computador) y el programa (las conexiones que serían establecidas entre estos componentes del hardware) la labor de "programación" requería sino del propio creador del computador si a un verdadero experto y conocedor de electrónica, principios de lógica digital y del problema mismo. Esto vino a cambiar con el concepto del programa almacenado, un concepto teórico muy importante que fue establecido por el matemático John von Neumann el 30 de junio de 1945 en un borrador sobre el diseño de la EDVAC (Electronic Discrete Variable Automatic Computer). A diferencia de los primeros computadores, von Neumann proponía que tanto el programa como sus datos fueran almacenados en la memoria del computador. Esto no solo simplificaba la labor de programación al no tener que llevar a cabo el recableado del computador sino que además libraba y generalizaba el diseño del hardware para hacerlo independiente de cualquier problema y enfocado al control y ejecución del programa. Este concepto fue tan importante y decisivo que dio lugar al concepto de la arquitectura de von Neumann, aún presente en nuestros días.

La alimentación del programa al computador se llegó a hacer de diversas formas. Primero a través de una serie de interuptores que permitian el ingreso de valores (en binario) directamente en la memoria del computador (una localidad a la vez). Posteriormente a través de pequeños teclados que permitian la introdución de valores en octal o hexadecimal, o mediante tarjetas perforadas. Esta última forma fue particularmente exitosa ya que permitía conservar el programa y alimentarlo una y otra vez según fuera requerido. Cintas de papel, y posteriormente los medios magnéticos, ofrecieron medios no volátiles de almacenamiento. La aparición de máquinas teletipo que trabajaban sobre papel de forma continua permitieron formas más sencillas de introducir el programa en la memoria del computador. Posteriormente se les incorporó una pantalla. Al principio de todo este periodo la programación se realizaba directamente en código máquina pero conforme los primeros ensambladores simbólicos hacen su aparición comienza la búsqueda de nuevas formas de expresar programas y de que estas sean cada vez más cercanas a como estamos acostubrados a la forma como expresamos nuestras ideas. Esto no sólo dio lugar al desarrollo de lenguajes de programación como una industria a la par de la del hardware sino también como una rama de estudio más dentro de la naciente ciencia de la computación.

La siguiente tabla no pretende ser una compilación exhaustiva, solamente busca ilustrar el desarrollo cronológico de algunos de los principales lenguajes de programación, sus versiones, y herramientas.

Año Lenguaje Descripción
1949-1950 Primeros ensambladores simbólicos En lugar de programar usando claves numéricas se usaba una serie de instrucciones sencillas llamadas códigos mnemónicos. Los primeros desarrollos son en la EDSAC. El siguiente ejemplo está pensado para funcionar bajo MVS JCL, éste imprimirá el mensaje "Hello, World!!!" a donde quiera que esté designada la salida en la tarjeta SYSPRINT DD.

*
* ESCRIBE "HELLO, WORLD!" A DONDE SEA QUE HAYA SIDO APUNTADA SYSPRINT
* EN EL LANZADOR JCL
*
HELLOPRT START 0                  INICIO
         PRINT NOGEN              RESERVA LAS MACRO EXPANSIONES
BEGIN    SAVE  (14,12)            GUARDA LOS REGISTROS DE ENTRADA
         LR    12,15              LOCALIZA....
         USING HELLOPRT,12        ...DONDE ESTAMOS
         ST    13,SAVE+4          GUARDA EL AREA ACTUAL DE DIRECCIONES
         LA    11,SAVE            APUNTA A UNA NUEVA AREA DE DIRECCIONES
         ST    11,8(13)           EN EL AREA ANTERIOR
         LR    13,11              MUEVE EL AREA DE DIRECCIONES GUARDADA
*
*
DOPUT    EQU   *
         PUT   SYSPRINT,HELLOMSG  ESCRIBE EL MENSAJE
         B     DOPUT              EN UN CICLO SIN FIN
*
* CODIGO NECESARIO PARA REGRESAR EL CONTROL AL MVS
*
         L     13,SAVE+4          OBTIENE AREA DE DIRECCIONES GUARDADA
         RETURN (14,12),RC=0      TO THE OPERATING SYSTEM
*
* DEFINICIONES PARA AREA DE TRABAJO Y ARCHIVOS
*
SAVE     DS    18F                PARA GUARDAR AREA LOCAL
HELLOMSG DC    C'Hello, world!!!'
SYSPRINT DCB   DSORG=PS,MACRF=PM,DDNAME=SYSPRINT,RECFM=FA,LRECL=133,BLKSIZE=133
1950 Short Order Code Desarrollado por John Mauchly, se considera el primer lenguaje de alto nivel.
1951 Betty Holberton crea un generador de ordenación y unión (sort-merge) de datos, y que es considerado como un predecesor de los modernos compiladores.
1951-1952 A-0 Primer compilador.
1954-1957 Fortran Desarrollado por John Backus. Su nombre resulta de la contracción del inglés formula translation. La primer especificación se escribió en 1954 pero fue hasta 1957 que se entregó el primer compilador funcional a la Westinghouse, para un computador IBM 704. Aunque originalmente incluía elementos de un lenguaje ensamblador, éste permitía a los programadores escribir expresiones algebraicas en lugar de la codificación necesaria para el cálculo. Revisiones al lenguaje y mejora son publicadas en 1958 (Fortran II), 1961 (Fortran IV), 1972 (Fortran 66).

C
C Versión Fortran
C
       Program Hello
       implicit none
       logical DONE
       DO while (.NOT. DONE)
         write(*,10)
       END DO
    10 format('Hello, world!!!')
       END
1959 Lisp Contracción de list processing. Desarrollado por John McCarthy aparece como un lenguaje en el que todo cálculo es expresado como la aplicación de una función sobre uno o más elementos. Los elementos en sí pueden ser funciones también. Pensado para aplicaciones de inteligencia Artificial.

;
; Versión Lisp
;
(DEFUN HELLO-WORLD ()
       (PRINT (LIST 'Hello, 'world!!!)))
1959-1960 COBOL En 1959 se crea The Committee on Data Systems Languages (Codasyl) para crear el Common Oriented Business Oriented Language. Pensado para aplicaciones de negocio y administrativas.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID. HELLOWORLD.
000300 DATE-WRITTEN. 02/05/96  21:04.
000400*     AUTHOR EDUARDO RODRIGUEZ AVILA
000500 ENVIRONMENT DIVISION.
000600 CONFIGURATION SECTION.
000700 SOURCE-COMPUTER. RM-COBOL.
000800 OBJECT-COMPUTER. RM-COBOL.
000900
001000 DATA DIVISION.
001100 FILE SECTION.
001200
100000 PROCEDURE DIVISION.
100100
100200 MAIN-LOGIC SECTION.
100300 BEGIN.
100400    DISPLAY " " LINE 1 POSITION 1 ERASE EOS.
100500    DISPLAY "Hello, world!!!" LINE 15 POSITION 1O.
100600    STOP RUN.
100700 MAIN-LOGIC/EXIT.
100800    EXIT.
1960 Algol 60 El primer lenguaje en incorporar las ideas de las estructuras de control y bloques de instrucciones fue el Algorithmic Language, mejor conocido como Algol. Revisiones posteriores incorporaron mejoras en 1968 (Algol 68).

;
; Versión Algol 60
;
BEGIN
FILE F (KIND=REMOTE);
EBCDIC ARRAY E [0:11];
REPLACE E BY "Hello, world!!!";
WHILE TRUE DO
  BEGIN
  WRITE (F, *, E);
  END;
END.
1962 APL Kenneth E. Iverson, de IBM, publica su libro A Programming Language. IBM entrega el primer intérprete en 1968.

Versión APL
'Hello, world!!!'
1964 BASIC John Kemeny y Thomas Kurtz desarrollan en el Dartmouth College el lenguaje cuyo nombre es derivado de las siglas de Beginner's All-purpose Symbolic Instruction Code.

10 REM
20 REM Versión BASIC
30 REM
40 print "Hello, world!!!"
50 goto 40
1965 PL/I Programming Language One, o PL/I, es como se conoció al lenguaje desarrollado por IBM como parte del desarrollo del System 360. La meta era el desarrollo de un lenguaje que sirviera tanto para usos científicos como financieros, usando estructuras de control. Así PL/I fue una combinación de Fortran, COBOL y Algol.


/* Versión PL/1 */

Hello: procedure options(main);

   declare My_String char(20) varying initialize('Hello, world!!!');
   put skip list(My_String);
end Test;
1967 Logo Este lenguaje fue desarrollado por W. Feurzeig, D. Bobrow and S. Papert para enseñar a los niños a programar. Su principal característica consiste en que sus comandos están pensados para controlar una tortuga imaginaria cuyos movimientos permiten hacer trazos en la pantalla.

;
; Versión Logo
;
make "saludo "Hello, world!!!
print :saludo
Simula Ole-Johan Dahl y Kristen Nygaard desarrollan en el Centro de Cómputo Noruego una versión de propósito general del lenguaje de programación Simula, el primer lenguaje orientado a objetos.

Begin
   while 1 = 1 do begin
        outtext ("Hello, world!!!");
        outimage;
   end;
End;
1968 Macsyma Macsyma fue el primer sistema de algebra por computadora interactivo, desarrollado en conjunto por el M.I.T y el U.S. Department for Advanced Research Projects Agency. En 1982 el M.I.T licenció el sistema a Symbolics, Inc., un constructor de estaciones de trabajo basadas en Lisp. En 1992, Macsyma, Inc., adquiere los derechos sobre el software Macsyma de Symbolics, Inc. Actualmente la empresa se encuentra en bacarrota. Macsyma incluye un lenguaje de programaci&oaacute;n propio derivado de Lisp.

/*
  Versión Macsyma
*/
hello():=(
   print ( "Hello, world!!!")
)$
1970 Forth Lenguaje extensible de alto nivel que combina características de lenguajes compilados e interpretados. Sus primeros usos fueron para control de radiotelescopios y otros equipos astronómicos. Su nombre originalmente fue Fourth (por FOURTH-generation computer language, algo ambicioso a decir verdad), pero desafortunadamente la computadora IBM 1130 en la que se desarrolló sólo aceptaba identificadores de cinco letras.

;
;Versión Forth
;
: hello
  begin
    true
    while
      ." Hello World "
    repeat
hello
1971 Pascal Niklaus Wirth, del Federal Institute of Technology, Zürich; Suiza; inicia el desarrollo de Pascal (nombrado así en honor del filósofo y matemático Blaise Pascal). El primer compilador estaá disponible al público en 1974 y es utilizado por muchas universidades desde entonces. Wirth había venido desarrollando al lenguaje desde 1968, pensado como una herramienta eduacional para la enseñanza sistémica de la programación de computadoras bajo estructuras de control y declarativas claras y simples.


(* Versión Pascal *)

Program Hello (input, output);

Begin
  writeln('Hello, world!!!');
End
1972 C Descendiente de B (creado por Kenneth Thompson), el cual fue derivado de otro lenguaje denominado BCPL (Basic Combined Programming Language, creado por Martin Richards), fue desarrollado por Dennis Ritchie, en aquel entonces programador de sistemas en AT&T Bell Laboratories. Considerado como un lenguage de alto nivel posee muchas características de bajo nivel como el manejar direcciones de memoria y bits, por tal motivo se le suele denominar de tipo intermedio híbrido.

/*
Versión C
*/

#include <stdio.h>

main()
{
   for (;;)
      {
        printf ("Hello, world!!!\n");
      }
}
Smalltalk Tomando de base las ideas de Alan Kay, Smalltalk es desarrollado por el Learning Research Group de los laboratorios PARC de Xerox.

COMMENT
"
  Versión Smalltalk
"!

Transcript show: 'Hello, world!!!';cr
Prolog Programming in Logic es el concepto en el que se basa el lenguaje desarrollado por Alain Colmerauer de la Universidad de Marsella. Y es a través de éste que populariza conceptos clave de resolución (en térmnos de deducción lógica) y unificación (a manera de búsqueda y empate de patrones) para llegar a las metas que el programador ha establecido junto con las reglas y conjuntos de datos sobre los que el programa de be apegarse y restringirse. Los programas son una secuencia de metas que deben ser obtenidas a satisfacción de las restricciones especificadas.

%
% Versión Prolog
%

hello :-
printstring ("Hello, world!!!");

printstring ([])
printstring ([H|T]) :- put (H), printstring (T).
1976-1977 Lucid Lucid es un lenguaje de programación para arquitecturas Dataflow, diseñado para experimentar con modelos de programación no von Neumann. En Lucid el programador define filtros o funciones de transformación que actuan en flujos de datos variables en el tiempo. Lucid soporta un conjunto de tipos de datos muy reducido: enteros, reales y símbolos. Diversas extesiones de Lucid han sido creadas, inlcuso una basada en formas llamada Plane Lucid.
1977-1978 AWK Desarrollado por Alfred V. Aho, Brian W. Kernighan y Peter J. Weinberger, su nombre deriva de las iniciales de sus creadores. AWK es un lenguaje orientado a la manipulación de textos, especialmente tomados de archivos. Su flexibilidad y potencia en la manipulación de cadenas de caracteres le permiten ser aplicado en una enorme variedad de problemas, por lo que a pesar de lo específico de su origen es considerado de propósito general.

#
# Versión AWK
#

{ print "Hello, world!!!" }
1979 VisiCalc La primera aplicación de hoja de cálculo, desarrollada por Dan Bricklin y Bob Frankston. Después de la popularidad y éxito que ganó como aplicación en la Apple II, el producto fue vendido a Lotus Development Corporation conduciendo al desarrollos de la hoja Lotus 1-2-3 para PC en 1983. Mucho más importante que una simple aplicación es el hecho de haber creado todo un nueno modelos de manejo de datos y programación.
Ada Después de un largo periodo de desarrollo el lenguaje DoD-1 es rebautizado en honor de Augusta Ada King, Condesa de Lovelace, hija del poeta Lord Byron y primera programadora en la historia al trabajar como asistente de Charles Babbage en el desarrollo de su Máquina Analítica. Es el resultado de un proyecto de estandarización del Departamento de Defensa de los USA iniciado por la gran diversidad de equipo y lenguajes de programación con que el DoD contaban en edificios y equipo. Se necesitaba un lenguaje único que pudiera ser usado en todos los computadores (incluyendo sistemas empotrados en equipo móvil) que incorporara características de abstracción de datos, multitarea, concurrencia y manejo de excepciones. Las versiones más difundidas con Ada 83 y Ada 95.

--
-- Versión Ada
--

with Text_Io;
use Text_Io;

procedure Hello is
begin
   put ("Hello, world!!!");
end Hello;
1980 Maple Maple es un paquete para procesamiento de matemáticas simbólicas y numéricas. Cuenta con su propio lenguaje de programación, conocido con el mismo nombre. Aunque muchas cosas pueden hacerse en este lenguaje, por su naturaleza, se trata de un lenguaje de propósito especial.


#
#Versión Maple
#
do
  print ('Hello, world!!!');
od:
Modula-2 Es un lenguaje procedural, de estructura orientada a bloques pensado tanto para propósitos educativos como aplicativos. Diseñado por Niklaus Wirth, corregía deficiencias estructurales de Pascal, lo mismo que proveía mejoras como una fuerte verificación de tipos, arreglos dinámicos y concurrencia.

(*
Versión Modula-2
*)

MODULE PrintHelloWorld;

FROM InOut IMPORT WriteString, WriteLn;

BEGIN
  WriteString('Hello world!');
  WriteLn;
END PrintHelloWorld.
1982 AutoCad Dialecto de Lisp usado como extensión de programación para un popular paquete de diseño de la compaña Autodesk. En adición de las tradicionales características de Lisp, ofrece facilidades para la manipulación de objetos CAD, archivos y para la interacción con el usuario a través de la interfaz AutoCAD.

;;
;;Versión AutoLisp
;;
(Defun c:HelloWorld ()
    (alert ("\nHello, world!!!\n"))
)
1983 C++ Bjarne Stroustrup, en AT&T Bell Laboratories, desarrolla una extensión orientada a objetos de C a la que denomina C++.

//
// Versión C++
//

#include <iostream.h>

int main()
{
   cout <<"Hello, world!!!" << '\n';
   return 0;
}

Tabla 5.- Desarrollo cronolólogico de algunos de los principales lenguajes y herramientas de programación.

Con el paso del tiempo los diversos lenguajes de programación han madurado. Hoy en día es posible categorizarlos por las características que han venido exhibiendo con dicha maduración. De manera que tenemos:

3. Compiladores e intérpretes: definiciones y conceptos.

Aunque es equivocado, es común encontrar referencias en documentación de productos, publicidad y textos (e inclusive escuchar a la gente del medio informático) utilizando los términos traductor, compilador e intérprete de una forma libre e indistinta. Estas palabras no se utilizan para identificar de manera genérica a un programa que nos permitiría poder programar una computadora. Debemos ser precisos al emplear estas palabras, ya que se refieren a programas de distinta naturaleza que realizan labores encaminadas a un objetivo específico y particular. Aunque la conducta manifestada pueda ser similar, su comportamiento interno definitivamente es diferente.

Genéricamente hablando, en ciencias de la computación, los procesadores de lenguajes son aquellos programas destinados a trabajar sobre una entrada que, por la forma como ha sido elaborada, pertenece a un lenguaje en particular reconocido o aceptado por el programa en cuestión. Los procesadores de lenguajes se clasifican como traductores o intérpretes.

Un traductor es un programa que recibe una entrada escrita en un lenguaje (el lenguaje fuente) a una salida perteneciente a otro lenguaje (el lenguaje objeto), conservando su significado. En términos computacionales esto significa que tanto la entrada como la salida sean capaces de producir los mismos resultados. Un intérprete, por otra parte, no lleva a cabo tal transformación; en su lugar obtiene los resultados conforme va analizando la entrada. Los traductores son clasificados en compiladores, ensambladores y preprocesadores.

Un compilador es un programa que recibe como entrada un programa escrito en un lenguaje de nivel medio o superior (el programa fuente) y lo transforma a su equivalente en lenguaje ensamblador (el programa objeto), e inclusive hasta lenguaje máquina (el programa ejecutable) pero sin ejecutarlo. Un compilador es un traductor. La forma de como llevará a cabo tal traducción es el objetivo central en el diseño de un compilador.

Un ensamblador es el programa encargado de llevar a cabo un proceso denominado de ensamble o ensamblado. Este proceso consiste en que, a partir de un programa escrito en lenguaje ensamblador, se produzca el correspondiente programa en lenguaje máquina (sin ejecutarlo), realizando:

Un precompilador, también llamado preprocesador, es un programa que se ejecuta antes de invocar al compilador. Este programa es utilizado cuando el programa fuente, escrito en el lenguaje que el compilador es capaz de reconocer (de aquí en adelante denominado lenguaje anfitrión-- en inglés host language), incluye estructuras, instrucciones o declaraciones escritas en otro lenguaje (el lenguaje empotrado-- en inglés embeded language). El lenguaje empotrado es siempre un lenguaje de nivel superior o especializado (e.g. de consulta, de cuarta generación, simulación, cálculo numérico o estadístico, etcétera). Siendo que el único lenguaje que el compilador puede trabajar es áquel para el cual ha sido escrito, todas las instrucciones del lenguaje empotrado deben ser traducidas a instrucciones del lenguaje anfitrión para que puedan ser compiladas. Así pu es un precompilador también es un traductor.

Los precompiladores son una solución rápida y barata a la necesidad de llevar las instrucciones de nuevos paradigmas de programación (e.g. los lenguajes de cuarta generación), extensiones a lenguajes ya existentes (como el caso de C y C++) y soluciones de nivel conceptual superior (por ejemplo paquetes de simulación o cálculo numérico) a código máquina utilizando la tecnología existente, probada, optimizada y confiable (lo que evita el desarrollo de nuevos compiladores). Facilitan la incorporación de las nuevas herramientas de desarrollo en sistemas ya elaborados (por ejemplo, la consulta a bases de datos relacionales substituyendo las instrucciones de acceso a archivos por consultas en SQL).

Resulta común encontrar que el flujo de proceso en los lenguajes de cuarta generación o de propósito especial puede resultar demasiado inflexible para su implantación en los procesos de una empresa, flujos de negocio o interacción con otros elementos de software y hardware, de aquí que se recurra o prefiera la creación de sistemas híbridos soportados en programas elaborados en lenguajes de tercera generación con instrucciones empotradas de nivel superior o propósito especial.

Un pseudocompilador es un programa que actua como un compilador, salvo que su producto no es ejecutable en ninguna máquina real sino en una máquina virtual. Un pseudocompilador toma de entrada un programa escrito en un lenguaje determinado y lo transforma a una codificación especial llamada código de byte. Este código no tendría nada de especial o diferente al código máquina de cualquier microprocesador salvo por el hecho de ser el código máquina de un microprocesador ficticio. Tal procesador no existe, en su lugar existe un programa que emula a dicho procesador, de aquí el nombre de máquina virtual.

La ventaja de los pseudocompiladores que permite tener tantos emuladores como microprocesadores reales existan, pero sólo se requiere un compilador para producir código que se ejecutará en todos estos emuladores. Este método es una de las respuestas más aceptadas para el problema del tan ansiado lenguaje universal o código portable independiente de plataforma.

Un intérprete es un programa que ejecuta cada una de las instrucciones y declaraciones que encuentra conforme va analizando el programa que le ha sido dado de entrada (sin producir un programa objeto o ejecutable). La ejecución consiste en llamar a rutinas ya escritas en código máquina cuyos resultados u operaciones están asociados de manera unívoca al significado de la instrucciones o declaraciones identificadas.

Los intérpretes son útiles para el desarrollo de prototipos y pequeños programas para labores no previstas. Presentan la facilidad de probar el código casi de manera inmediata, sin tener que recurrir a la declaración previa de secciones de datos o código, y poder hallar errores de programación rápidamente. Resultan inadecuados para el desarrollo de complejos o grandes sistemas de información por ser más lentos en su ejecución.

4. Visión general del proceso de compilación.

La figura 1 presenta un diagrama que ilustra de forma general las dos fases que componen al proceso de compilación y cada fase desglosada en sus etapas componentes. En una primera fase de análisis1 el programa es descompuesto en sus elementos fundamentales. En la posterior fase de síntesis2 es construido el programa ejecutable correspondiente a los elementos identificados en la fase previa. El proceso es irreversible e inclusive puede considerarse destructivo, ya que no hay forma de reconstituir el programa fuente a partir del ejecutable3. Únicamente por facilidad descriptiva, el proceso es presentado con las etapas que componen a cada fase perfectamente diferenciadas y separadas; en la práctica se ha demostrado que productos muy rápidos y eficientes pueden ser desarrollados alterando el orden de algunas etapas o entremezclándolas.


Figura 1.- Etapas del proceso de compilación.

La entrada a este proceso es por supuesto el programa fuente. Por lo general éste es un archivo que es creado por el usuario como un texto ASCII con o sin un formato específico aunque también puede ser el resultado de algún otro proceso. A partir de este archivo diversos pasos pueden ser llevados a cabo:

Al final, como producto de todo este proceso, lo que se obtiene es un programa escrito en código máquina que puede ser cargado en memoria y ejecutado. El proceso seguido por un intérprete es ligeramente diferente, ya que mientras que cubre todas las etapas de análisis no cuenta con una fase síntesis. Un intérprete no genera código, se limita a invocar rutinas ya escritas (proceso muchas veces llamado de interpretación). La siguiente figura ilustra esto.


Figura 2.- Etapas del proceso de interpretación.

En el caso de un pseudo-compilador, cuyo caso mejor conocido es el de Java, la diferencia consiste en el código generado. Mientras que todas las etapas de un compilador son cubiertas, el programa ejecutable no es creado para ser ejecutado en un procesador "real" sino para uno "hipotético" o "imaginario" y conocido generalmente como máquina virtual. La máquina virtual es otro programa cuyo funcionamiento simula al de un procesador. Este procesador recibe de entrada el pseudo-código creado por el compilador y procede a la ejecución de las instrucciones contenidas en éste; puede verse que no se trata mas que de un intérprete muy sencillo.


Figura 3.- Etapas del proceso de pseudo-compilación.

La siguiente figura ilustra con mayor detalle lo que pasa en cada una de las etapas del proceso de compilación. El procesamiento de instrucciones de un lenguaje huesped (como puede ser SQL) correría a cargo del pre-procesador, siendo transformadas instrucciones del lenguaje anfitrión. Durante la fase de análisis léxico el scanner se encarga de identificar cada uno de los elementos usados para escribir el programa fuente, substituyendo a cada uno de estos por un código numérico único (tokens). En este proceso se eliminan comentarios y espacios en blanco. Los tokens son alimentados al analizador sintáctico que valida que su disposición está acorde a las reglas del lenguaje. Validado este el analizador semántico procede a identificar el propósito de las diversas secuencias de tokens y buscará generar representaciones intermedias de cada acción o directamente código máquina. Este posteriormente es optimizado.


Figura 4.- Detalle del flujo de datos y acciones en el proceso de compilación.

1Análisis: Dado un sistema, identificar los elementos constituyentes, las interrelaciones entre &eeacute;stos, y determinar la conducta creada.
2Síntesis: Dado un conjunto de elementos y estableciendo un determinado número de interrelaciones entre éstos, crear uno de muchos posibles sistemas con una determinada conducta.
3El "descompilar" un programa sólo es posible si se cuenta con información de depuración, generada por el compilador. Mientras que es posible "desensamblar" un programa, sin información adicional que permita asociar secuencias de instrucciones ensamblador a instrucciones de nivel alto, es imposible reconstruir el programa fuente a partir del código ejecutable.
Este texto puede ser copiado y reproducido libremente mientras su contenido no sea alterado, se cite la fuente y referencias. Las marcas registradas son responsabilidad de sus dueños y el autor de este texto no tiene relación alguna con estos. M. en C. Eduardo René Rodríguez Avila. © Todos los derechos reservados.
Ultima actualización: .