Introducción
En los años 40 códigos numéricos y un secuenciador de cableado constituían un código de máquina.
Como los códigos numéricos eran muy complejos de manejar se generaron neumónicos y se construyó el lenguaje ensamblador para facilitar la tarea.
El primer lenguaje de alto nivel desarrollado fue FORTRAN, que fue considerado el primer traductor (compilador) pero estaba específicamente dirigido al hardware que se empleaba.
En Europa, en forma paralela apareció un lenguaje que trataba ser independiente del hardware, basado en las gramáticas de Chomsky, así fue creado el ALGOL 58.
Recién en 1958 Strong y su grupo propuso la división del compilador en dos fases (front end y back end) lo que permitió que pueda ser utilizado sobre diferentes hardware.
Siguiendo con la historia, rápidamente podemos comentar que a fines de los 50 Rabin y Scott proponen implementar autómatas deterministas y no deterministas en el análisis lexicográfico de los programas fuentes, Sheridan en el 59, describe un método de parking Luego Floyd introduce técnicas de precedencia de operadores y funciones de precedencia. El parsing descendente recursivo se utilizó en el 61 y en el 68 se definen las gramáticas LL y los parsers predictivos.
En el año 68 Johnson a partir de expresiones regulares construye analizadores léxicos. En definitiva Chomsky y sus trabajos fueron la base de los métodos de análisis léxico y sintáctico. En los 70 surgen los métodos SLR y LALR de parser LR quedando su implementación en los generadores automáticos de parsers. Johnson crea el generador de analizadores sintácticos para funcionar en UNIX.
…………………………..
La generación de código intermedio como tarea de un compilador permite escribir un fuente en cualquier lenguaje a un código independiente del mismo e independiente de la plataforma donde se ejecutará.
Objetivo
El ICML (Intermediate Code Markup Language) y el GSML (Grammar Spec Markup Language) son dos propuestas de simplificación de especificación de código intermedio y gramáticas (respectivamente).
Están inspiradas en el compilador de BNF javacc y jtree, aunque van un poco mas allá de los mismos.
En un principio, estarán basadas en herramientas ya existentes (Lex y Yacc), pero apuntan a ser independientes de los mismos.
Fundamentación
Una de las partes mas complejas del diseño de compiladores es la adición de acciones semánticas a una gramática ya hecha y pulida.
Veamos esta situación: el programador acaba de terminar con la gramática, y está muy contento de verla prolija, sintética y elegante. Un verdadero trabajo de científico, sobre todo la parte de eliminar ese bendito conflicto "shift-reduce" que no aparecía por ningún lado. Atrás quedó el agregar las reglas de recuperación ante el error con su cascada de "reduce-reduce", y otros mensajes extravagantes que emitía el yacc (¿qué significa "pila demasiado chica"? ¿por qué la regla 1034 no se reduce nunca?, ¿me paso a Linux?, etc., etc. ).
Pero ahora viene lo peor ... las acciones semánticas.
De por si solo, este monstruoso trabajo no hace nada mas importante que decidir si un programa fuente es correcto o no, bastante poca cosa después de todo lo que se sufrió.
Manos a la obra, y empecemos a definir una código intermedio suficientemente simple y útil. Mas fácil decirlo que hacerlo.
Al tiempo de luchar con triplas, cuádruplas, un-millón-plas, queda mas o menos plasmado un código no demasiado vergonzoso, y el programador comienza a transpirar poniendo las acciones semánticas que lo generen.
Cada vez que piensa que el fin está mas cerca, descubre que alguna regla provoca atributos sintetizados ¿cambio la regla o pongo una acción semántica intermedia? (ni piensa en cambiar la gramática porque fue demasiado trabajo, pero poner una acción intermedia es poco elegante ...), se le aparece algún caso de triplo que no había previsto y tiene que cambiar todos los ".h" del sistema, y así hasta el infinito.
Todo esto para que, cuando entrega el trabajo, con el orgullo propio de haber hecho algo terriblemente difícil y complicado, el jefe (o en nuestro caso, el profesor) le objete que su código es ilegible, o que sería una buena idea agregar otra forma de pasar parámetros a las funciones. Vuelta a empezar ...
¿Por qué no existe una separación entre gramática y semántica como la que ya hay con la léxica? esto resolvería una gran cantidad de cosas:
- Una gramática terminada solo hay que modificarla ante nuevos requerimientos.
- Modificaciones a la gramática impactan muy poco en la semántica.
- El "parser" genera el árbol de análisis sintáctico independientemente de cual sea el lenguaje objeto.
- Las semánticas pueden dividirse en varios programas que modifican el árbol un poco por vez. Esto es especialmente útil para realizar optimización sobre el código.
Nuestro objetivo es generar un código intermedio "cuasi-standard" que permita resolver la separación entre las estapas del compilador.
Desarrollo
¿Qué es XML?
XML es la sigla del inglés eXtensible Markup Language (lenguaje de marcado ampliable o extensible) desarrollado por el World Wide Web Consortium (W3C).
Su objetivo principal es conseguir una página web más semántica. Aunque una de las principales funciones con las que nace sería suceder al HTML, separando la estructura del contenido y permitiendo el desarrollo de vocabularios modulares, compatibles con cierta unidad y simplicidad del lenguaje (objetivo que se viene desarrollando a través de la especificación XHTML), tiene otras aplicaciones entre las que destaca su uso como estándar para el intercambio de datos entre diversas aplicaciones o software con lenguajes privados como en el caso del SOAP.
Al igual que el HTML, se basa en documentos de texto plano en los que se utilizan etiquetas para delimitar los elementos de un documento. Sin embargo, XML define estas etiquetas en función del tipo de datos que está describiendo y no de la apariencia final que tendrán en pantalla o en la copia impresa, además de permitir definir nuevas etiquetas y ampliar las existentes.
Son varios los vocabularios desarrollados en XML con el fin de ampliar sus aplicaciones. Podemos considerar fundamentales: XHTML, XSL-FO y XSLT, XLink, XPointer y Schema. Además, existen también versiones para usos específicos, como MathML (fórmulas matemáticas), SVG (gráficos vectoriales), RSS (sindicación de noticias), GML (información geográfica) o XBRL (partes financieros).
wikipedia
¿Qué es ICML?
El icml es una propuesta de código intermedio basado en en XML, en el cual se definen los tags necesarios para traducir la mayoría de los lenguajes de la actualidad. A fines de comenzar con este proyecto, se tomarán los tags necesarios para generar C y Pascal, pero el objetivo a mediano plazo es extenderlo a lenguajes con orientación a objetos (C++, Java y C#), y definir un mecanismo de extensión que permita definir otros "tags" (SQL).
Veamos un ejemplo:
Como se puede observar, el árbol es independiente del lenguaje de entrada, y del uso final que se le quiera dar. Por ejemplo, un optimizador de código que recibiera esta salida podría inmediatamente descubrir que dentro del árbol del "*", solo hay constantes, con lo cual podría reducirlo en tiempo de compilación (independientemente del lenguaje de origen), un graficador podría representar el árbol sin tener que hacer ningún procesamiento demasiado sofisticado, etc.
Como se puede observar, el árbol es independiente del lenguaje de entrada, y del uso final que se le quiera dar. Por ejemplo, un optimizador de código que recibiera esta salida podría inmediatamente descubrir que dentro del árbol del "*", solo hay constantes, con lo cual podría reducirlo en tiempo de compilación (independientemente del lenguaje de origen), un graficador podría representar el árbol sin tener que hacer ningún procesamiento demasiado sofisticado, etc.