Sei sulla pagina 1di 50
COMPILADORES Principios, Técnicas y Herramientas spanish edition - all rights reserved © it] CAPITULO | Introduccion a la compilacién Los principios y técnicas de escritura de compiladores son tan amplios que las ideas encontradas en este libro se usaran muchas veces en la carrera de un cientifico de la computacion. La escritura de compiladores comprende los lenguajes de progra- maci6n, la arquitectura de computadores, la teoria de lenguajes, los algoritmos y la ingenieria de sofiware. Por fortuna, con algunas técnicas basicas de escritura de compiladores se pueden construir traductores para una gran variedad de lenguajes y maquinas. En este capitulo, se introduce el tema de la compilacién describiendo los componentes de un compilador, el entorno en el que trabajan los compiladores y algunas herramientas de software que facilitan la construcci6n de compiladores. 1,1 COMPILADORES A grandes rasgos, un compilador es un programa que lee un programa escrito en un lenguaje, el lenguaje fuente, y lo traduce a un programa equivalente en otro len- guaje, el lenguaje objeto (véase Fig. 1.1). Como parte importante de este proceso de traducci6n, el compilador informa a su usuario de la presencia de errores en el pro- grama fuente. programa, fuente programa ——*|_ compilador objeto | mensajes de error Fig. L.1. Un compilador. A primera vista, la diversidad de compiladores puede parecer abrumadora. Hay miles de lenguajes fuente, desde los lenguajes de programaci6n tradicionales, como FORTRAN 0 Pascal, hasta los lenguajes especializados que han surgido virtual- mente en todas las areas de aplicacién de la informatica. Los lenguajes objeto son igualmente variados; un lenguaje objeto puede ser otro lenguaje de programacion 0 2. INTRODUCCION A LA COMPILACION el lenguaje de maquina de cualquier computador entre un microprocesador y un su- percomputador. Los compiladores a menudo se clasifican como de una pasada, de multiples pasadas, de carga y ejecucin, de depuraci6n o de optimacion, depen- diendo de cémo hayan sido construidos o de qué funcién se supone que realizan. A pesar de esta aparente complejidad, las tareas basicas que debe realizar cualquier compilador son esencialmente las mismas. Al comprender tales tareas, se pueden construir compiladores para una gran diversidad de lenguajes fuente y maquinas ob- jeto utilizando las mismas técnicas basicas. Nuestro conocimiento sobre como organizar y escribir compiladores ha aumen- tado mucho desde que comenzaron a aparecer los primeros compiladores a princi- pios de los afios cincuenta. Es dificil dar una fecha exacta de la aparicion del primer compilador, porque en un principio gran parte del trabajo de experimentacion y aplicacién se realizé de manera independiente por varios grupos. Gran parte de los primeros trabajos de compilacién estaba relacionada con la traduccién de formulas aritméticas a codigo de maquina. En la década de 1950, se consideré a los compiladores como programas notable- mente dificiles de escribir. El primer compilador de FORTRAN, por ejemplo, ne- cesité para su implantacion 18 aios de trabajo en grupo (Backus y otros [1975]). Desde entonces, se han descubierto técnicas sistematicas para manejar muchas de las importantes tareas que surgen en la compilacion. También se han desarrollado buenos lenguajes de implantacién, entornos de programacién y herramientas de software. Con estos avances, puede hacerse un compilador real incluso como pro- yecto de estudio en un curso de un semestre sobre disefio de compiladores. Modelo de anilisis y sintesis de la compilacion En la compilacién hay dos partes: andlisis y sintesis. La parte del anilisis divide al programa fuente en sus elementos componentes y crea una representacién inter- media del programa fuente. La parte de la sintesis construye el programa objeto de- seado a partir de la representacion intermedia. De las dos partes, la sintesis es la que requiere las técnicas mds especializadas. En la seccidn 1.2 se examinaré el anilisis de manera informal y en la seccion 1.3 se esbozara la forma de sintetizar el codigo objeto en un compilador estandar. Durante el anilisis, se determinan las operaciones que implica el programa fuente y se registran en una estructura jerérquica llamada Arbol. A menudo, se usa una clase especial de drbol llamado arbol sintactico, donde cada nodo representa una opera- cidn y los hijos de un nodo son los argumentos de la operacién. Por ejemplo, en la figura 1.2 se muestra un drbol sintactico para una proposicién de asignacién. z™“N posicién + aN anicial * 2z™“N velocidad 60 Fig. 1.2. Arbol sintactico para posicion := inicial + velocidad + 60 11 COMPILADORES 3 Muchas herramientas de software que manipulan programas fuente realizan pri- mero algun tipo de andlisis. Algunos ejemplos de tales herramientas son: L Editores de estructuras. Un editor de estructuras toma como entrada una se- cuencia de érdenes para construir un programa fuente. El editor de estructuras , no sdlo realiza las funciones de creacién y modificacién de textos de un editor de textos ordinario, sino que también analiza el texto del programa, impo- niendo al programa fuente una estructura jerérquica apropiada. De esa manera, el editor de estructuras puede realizar tareas adicionales utiles para la prepara- cién de programas. Por ejemplo, puede comprobar si la entrada esté formada correctamente, puede proporcionar palabras clave de manera automatica (por ejemplo, cuando el usuario escribe while, el editor proporciona el correspon- diente do y le recuerda al usuario que entre las dos palabras debe ir un condi- cional) y puede saltar desde un begin o un paréntesis izquierdo hasta su co- trespondiente end o paréntesis derecho. Ademés, la salida de tal editor suele ser similar a la salida de la fase de andlisis de un compilador. Impresoras estéticas, Una impresora estética analiza un programa y lo imprime de forma que la estructura del programa resulte claramente visible. Por ejemplo, Jos comentarios pueden aparecer con un tipo de letra especial, y las proposicio- nes pueden aparecer con una indentacién proporcional a la profundidad de su anidamiento en la organizacién jerarquica de las proposiciones. Verificadores estaticos. Un verificador estatico lee un programa, lo analiza e in- tenta descubrir errores potenciales sin ejecutar el programa. La parte del anilisis a menudo es similar a la que se encuentra en los compiladores de optimacién del tipo estudiado en el capitulo 10. Asi, un verificador estatico puede detectar si hay partes de un programa que nunca se podran ejecutar o si cierta variable se usa antes de ser definida. Ademas, puede detectar errores de légica, como in- tentar utilizar una variable real como apuntador, empleando las técnicas de ve- Tificacion de tipos que se analizan en el capitulo 6. AIntérpretes. En lugar de producir un programa objeto como resultado de una traduccion, un intérprete realiza las operaciones que implica el programa fuente. Para una proposicion de asignacion, por ejemplo, un intérprete podria construir un Arbol como el de la figura 1.2, y después efectuar las operaciones de los no- dos conforme “recorre” el arbol. En la raiz descubriria que tiene que realizar una asignacin, y llamaria a una rutina para evaluar la expresién de la derecha y después almacenaria el valor resultante en la localidad de memoria asociada con el identificador posicién. En el hijo derecho de la raiz, la rutina descubri- tia que tiene que calcular la suma de dos expresiones. Se llamaria a si misma de manera recursiva para calcular el valor de la expresi6n ve locidad*60. Des- pués sumaria ese valor al valor de la variable inicial. Muchas veces los intérpretes se usan para ejecutar lenguajes de ordenes, pues cada operador que se ejecuta en un lenguaje de érdenes suele ser una invocacién de una rutina compleja, como un editor o un compilador. Del mismo modo, algunos lenguajes de “muy alto nivel”, como APL, normalmente son interpre- tados, porque hay muchas cosas sobre los datos, como el tamafio y la forma de las matrices, que no se pueden deducir en el momento de la compilacién. 4 INTRODUCCION A LA COMPILACION Tradicionalmente, se concibe un compilador como un programa que traduce un programa fuente, como FORTRAN, al lenguaje ensamblador o de maquina de al- gun computador. Sin embargo, hay lugares, al parecer, no relacionados donde la tecnologia de los compiladores se usa con regularidad. La parte de andlisis de cada uno de los siguientes ejemplos es parecida a la de un compilador convencional. 1. Formadores de textos. Un formador de textos toma como entrada una cadena de caracteres, la mayor parte de la cual es texto para componer, pero alguna in- cluye érdenes para indicar parrafos, figuras o estructuras matematicas, como subindices 0 superindices. En la siguiente seccin se menciona algo del anilisis que realizan los forniadores de textos. 2. Compiladores de circuitos de silicio. Un compilador de circuitos de silicio tiene un lenguaje fuente similar o idéntico a un lenguaje de programacién convencio- nal. Sin embargo, las variables del lenguaje no representan localidades de memoria, sino sefiales l6gicas (0 6 1) o grupos de sefales en un circuito de con- mutacién. La salida es el disefio de un circuito en un lenguaje apropiado. Véanse Johnson [1983], Ullman [1984], 0 Trickey [1985] sobre un andlisis de los com- piladores de circuitos de silicio. 3. Intérpretes de consultas. Un intérprete de consultas traduce un predicado que contiene operadores relacionales y booleanos a Ordenes para buscar en una base de datos registros que satisfagan ese predicado. (Véase Ullman [1982] 0 Date [1986].) El contexto de un compilador Ademas de un compilador, se pueden necesitar otros programas para crear un pro- grama objeto ejecutable. Un programa fuente se puede dividir en modulos alma- cenados en archivos distintos. La tarea de reunir el programa fuente a menudo se confia a un programa distinto, llamado preprocesador. El preprocesador también puede expandir abreviaturas, llamadas macros, a proposiciones del lenguaje fuente. La figura 1.3 muestra una “compilacién” tipica. El programa objeto creado por el compilador puede requerir procesamiento adicional antes de poderlo ejecutar. El compilador de la figura 1.3 crea cédigo en lenguaje ensamblador el cual es traducido por un ensamblador a cédigo de maquina y después se enlaza a algunas rutinas de biblioteca para producir el codigo que realmente se ejecute en la maquina, En las dos secciones siguientes se estudiardn los componentes de un compilador; los programas restantes de la figura 1.3 se analizan en la secci6n 1.4. 1.2 ANALISIS DEL PROGRAMA FUENTE En esta seccién se introduce el andlisis y se ilustra su uso en algunos lenguajes de formaci6n de textos. Este tema se trata con mas detalle en los capitulos 2 al 4 y en el 6, En la compilaci6n, el analisis consta de tres fases: 1. Andlisis lineal, en el que la cadena de caracteres que constituye el programa fuente se lee de izquierda a derecha y se agrupa en componentes léxicos, que son secuencias de caracteres que tienen un significado colectivo. we 2 ANALISIS DEL PROGRAMA FUENTE estructura del programa fuente y preprocesador Ld programa fuente fii Ps compilador ' programa objeto en lenguaje ensamblador v ‘ cédigo de maquina relocalizable biblioteca, editor de carga y enlace }«—— archivos objeto relocalizables ' codigo de maquina absoluto Fig. 1.3. Sistema para procesamiento de un lenguaje. Anidilisis jerdrquico, en el que los caracteres 0 los componentes léxicos se agru- pan jerarquicamente en colecciones anidadas con un significado colectivo. Anilisis seméntico, en el que se realizan ciertas révisiones para asegurar que los componentes de un programa se ajustan de un modo significativo. Analisis léxico En un compilador, el andlisis lineal se llama andilisis /éxico 0 exploracién. Por ejen- plo, en el anilisis léxico los caracteres de la proposicién de asignacion posicién := inicial + velocidad + 60 se agruparian en los componentes léxicos siguientes: Pee een El identificador posicién. El simbolo de asignacién El identificador inicial. El signo de suma. El identificador velocidad. El signo de multiplicacion. El numero 60. Los espacios en blanco que separan los caracteres de estos componentes léxicos nor- malmente se eliminan durante el analisis léxico. 6 INTRODUCCION A LA COMPILACION Analisis sintactico El andlisis jerarquico se denomina andlisis sintdetico. Este implica agrupar los com- ponentes léxicos del programa fuente en frases gramaticales que el compilador uti- liza para sintetizar la salida. Por lo general, las frases gramaticales del programa fuente se representan mediante un arbol de anilisis sintactico como el que se ilustra en la figura 1.4, Proposicion de asignacion Beer de Se identificador expresion l 1 posicion + expresin expresion | | identificador 1 expresion eipresion inicial 1 | identificador mimero | | velocidad 60 Fig. 1.4. Arbol de analisis sintdctico para posicién := inicial + velocidad + 60. En la expresion inicial + velocidad * 60, la frase velocidad * 60 es una unidad Idgica, porque las convenciones usuales de las expresiones aritméticas indi- can que la multiplicacién se hace antes que la suma. Puesto que la expresién ini - cial + velocidad va seguida de un +, no se agrupa en una sola frase indepen- diente en la figura 1.4. La estructura jerarquica de un programa normalmente se expresa utilizando re- glas recursivas. Por ejemplo, se pueden dar las siguientes reglas como parte de la de- finicién de expresiones: Cualquier identificador es una expresion. Cualquier mimero es una expresion. Si expresién, y expresién, son expresiones, entonces también lo son eee expresion, + expresiény expresion, * expresiony ( expresion, ) Las reglas (1) y (2) son reglas basicas (no recursivas), en tanto que la regla (3) de- fine expresiones en funcidn de operadores aplicados a otras expresiones. Asi, por la regla (1), inicial y velocidad son expresiones. Por la regla (2), 60 es una expresin, mientras que por la regla (3), primero podemos inferir que velocidad + 60 es una expresidn, y finalmente, que inicial + velocidad « 60 tambien es una expresion. 1.2 ANALISIS DEL PROGRAMA FUPNTE 7 De manera similar, muchos lenguajes definen recursivamente las proposiciones mediante reglas como: 1. Si identificador, es un idemtificador y expresién: es una expresién, entonces identificador, += expresion; es una f-oposicién. 2. Si expresién, es una expresién y proposicién, es una proposicién, entonces while ( expresién, ) do proposiciény if ( expresidn, ) then proposiciéns son proposiciones. La division entre anilisis léxico y anilisis sintéctico es algo arbitraria. General- mente se elige una division que simplifique la tarea completa del andlisis. Un factor para determinar la division es si una construccin del lenguaje fuente es inherente- mente recursiva 0 no. Las construcciones léxicas no requieren recursién, mientras que las construcciones sintacticas suelen requerirla, Las gramaticas independientes del contexto son una formalizacion de reglas recursivas que se pueden usar para guiar el andlisis sintactico, Estas gramdticas se dan a conocer en el capitulo 2 y se estudian ampliamente en el capitulo 4. Por ejemplo, no se requiere recursién para reconocer los identificadores, que suelen ser cadenas de letras y digitos que comienzan con una letra, Normalmente, se reconocen los identificadores por el simple examen del flujo de entrada, espe- rando hasta encontrar un cardcter que no sea ni letra ni digito, y agrupando después todas las letras y digitos encontrados hasta ese punto en un componente Iéxico iden- tificador. Los caracteres asi agrupados se registran en una tabla, liamada tabla de simbolos, y se retiran de la entrada, para que pueda empezar el procesamiento del siguiente elemento léxico. Por otra parte, esta clase de andlisis léxico lineal no es suficientemente poderoso para analizar expresiones 0 proposiciones. Por ejemplo, no podemos emparejar de manera apropiada los paréntesis de las expresiones, 0 las palabras begin y end en proposiciones sin imponer alguna clase de estructura jerérquica o de anidamiento a Ja entrada. El arbol de anilisis sintactico de la figura 1.4 describe ia estructura sintactica de Ja entrada. Una representaci6n interna mas comuin de esta estructura sintdctica es 2o™N ZaoN posicién + posicién + ZN ZON inieia2 * inieial * ZoaN z™ velocidaa 60 velocidad entareal | (a) tb) 60 -5. El analisis semantico inserta una conversién de entero a real.

Potrebbero piacerti anche