You are on page 1of 13

4o Ingenier Informtica a a

II26 Procesadores de lenguaje


Estructura de los compiladores e intrpretes e Esquema del tema
1. Introduccin o 2. Etapas del proceso de traduccin o 3. La interpretacin o 4. La arquitectura real de compiladores e intrpretes e 5. Algunos conceptos de teor de lenguajes formales a 6. Resumen del tema

1.

Introduccin o

Tanto los compiladores como los intrpretes son programas de gran complejidad. Afortunadae mente, se sabe suciente acerca de cmo estructurarlos y hay sucientes herramientas formales o para que la complejidad se reduzca a niveles razonables. En este tema veremos en qu fases se e divide un compilador o un intrprete. Veremos tambin qu tienen en comn y cmo dieren entre e e e u o s compiladores e intrpretes. e La principal herramienta formal para el desarrollo de compiladores e intrpretes es el concepto e de lenguaje formal. Es necesario tener cierta familiaridad con los fundamentos de esta teor y, en a especial, con los lenguajes regulares e incontextuales. En este tema haremos un ligero repaso a los aspectos ms relevantes para la asignatura. a

2.

Etapas del proceso de traduccin o

Podemos modelar el proceso de traduccin entre dos lenguajes como el resultado de dos etapas. o En la primera etapa se analiza la entrada para averiguar qu es lo que se intenta comunicar. Esto e es lo que se conoce como anlisis. El fruto de esta etapa es una representacin de la entrada que a o permite que la siguiente etapa se desarrolle con facilidad. La segunda etapa, la s ntesis, toma la representacin obtenida en el anlisis y la transforma en su equivalente en el lenguaje destino. o a En el caso de la interpretacin, se utiliza la representacin intermedia para obtener los resulo o tados deseados.

2.1.

Anlisis a

El objetivo de esta etapa es obtener una representacin de la entrada que nos permita realizar o la s ntesis o la interpretacin con comodidad. La representacin que nosotros utilizaremos es la o o que se llama rbol de sintaxis abstracta. Un ejemplo ser la traduccin siguiente: a a o asignacin o

valor= valor+inc; /* Actualizamos */

idvalor suma

idvalor idinc El paso de la entrada al rbol de sintaxis abstracta no es trivial. Para facilitarlo, se divide la a tarea en varias partes. Supn que tuvieras que describir un lenguaje de programacin. Una manera o o

II26 Procesadores de lenguaje

de hacerlo ser comenzando por describir cules son las unidades elementales tales como identia a cadores, palabras reservadas, operadores, etc. que se encuentran en la entrada. Despus podr e as describir cmo se pueden combinar esas unidades en estructuras mayores tales como expresiones, o asignaciones, bucles y dems. Finalmente, especicar una serie de normas que deben cumplirse a as para que el programa, adems de estar bien escrito, tenga signicado. Estas normas se reeren a a aspectos tales como que las variables deben declararse o las reglas que se siguen para decidir los tipos de las expresiones. Las tres fases que hemos mencionado tienen su reejo en las tres fases en que se divide el anlisis: a Anlisis lxico: se encarga de la divisin de la entrada en componentes lxicos. a e o e Anlisis sintctico: se encarga de encontrar las estructuras presentes en la entrada. a a Anlisis semntico: se encarga de comprobar que se cumplen las restricciones semnticas del a a a lenguaje. 2.1.1. Anlisis lxico a e

En esta fase se analiza la entrada carcter a carcter y se divide en una serie de unidades a a elementales: los componentes lxicos. Cada uno de estos componentes se clasica con su categor e a y puede recibir un etiquetado con cierta informacin (por ejemplo un entero tendr una etiqueta o a indicando su valor). El criterio que se emplea para clasicar cada componente es su pertenencia o no a un lenguaje (generalmente regular). Esta fase adems se encarga de ltrar elementos tales a como los blancos y los comentarios. En nuestro ejemplo, tendr amos como categor los identicadores, la suma, la asignacin y as o el punto y coma. Podemos suponer que los identicadores son secuencias de letras y d gitos que comienzan por una letra. Adems, hay otros componentes que se ltran o, ms formalmente, son a a omitidos: los blancos y los comentarios. Teniendo en cuenta esto, nuestro analizador lxico ve: e
v a a m l o o s r = * / v a l o r + i n c ; / * A c t u a l i z

Y lo que pasa al sintctico es: a


idvalor asig idvalor suma idinc pyc

Donde hemos asumido que id es el componente lxico que representa los identicadores; asig repree senta la asignacin; suma, las sumas y pyc, el punto y coma. Como puedes ver, han desaparecido o tanto los blancos como los comentarios. 2.1.2. Anlisis sintctico a a

Partiendo de lo que ha recibido del analizador lxico, la tarea del analizador sintctico consiste e a en ir descubriendo las estructuras presentes en el cdigo de acuerdo con una gramtica incontextual. o a A partir de las estructuras que ha encontrado, el analizador sintctico construye un rbol sintctico a a a (que no hay que confundir con el rbol de sintaxis abstracta comentado antes). a Para especicar las construcciones que se permiten, se suelen emplear gramticas incontexa tuales, que veremos luego. En nuestro caso podemos pensar que las reglas que se siguen son que una asignacin se compone de un identicador, seguido de un s o mbolo de asignacin, seguio do de una expresin y de un punto y coma. Esto se escribe en la gramtica en forma de regla: o a Asig id asig Expr pyc. Anlogamente, podemos decir que una expresin es bien un identicaa o dor, bien la suma de dos expresiones. En reglas: Expr Expr id Expr suma Expr

Estructura de los compiladores e intrpretes e

El rbol sintctico nos permite expresar cmo se puede fabricar (formalmente, derivar) la a a o entrada a partir de las reglas. En nuestro caso, el rbol tiene un aspecto similar a: a Asig Expr Expr
idvalor asig idvalor suma

Expr
idinc pyc

Es interesante darse cuenta de que, tanto en las reglas como en la construccin del rbol, se o a hace caso omiso de los posibles atributos de los componentes lxicos; unicamente se tiene en cuenta e su categor a. 2.1.3. Anlisis semntico a a

La ultima fase del anlisis, el anlisis semntico, toma como entrada el rbol sintctico y a a a a a comprueba si, adems de las restricciones sintcticas, se cumplen otras restricciones impuestas a a por el lenguaje y que no pueden ser comprobadas mediante una gramtica incontextual. Algunos a ejemplos de estas restricciones son la necesidad de declarar las variables antes de usarlas, las reglas de tipos o la coincidencia entre los parmetros de las funciones en las deniciones y las llamadas. a Como salida de esta fase, se obtiene una representacin semntica, por ejemplo el rbol de sintaxis o a a abstracta comentado antes. Adems, se ha comprobado que tanto valor como inc estn declaradas a a y con tipos compatibles.

2.2.

S ntesis

Una vez analizado el programa de entrada, es necesario generar cdigo, a ser posible ecieno te, para la mquina objetivo. Supongamos que tenemos L lenguajes fuente y queremos escribir a compiladores para M mquinas distintas. La aproximacin inmediata, escribir un compilador para a o cada par lenguaje-mquina, supone escribir L M compiladores. Sin embargo, si los lenguajes son a razonablemente parecidos (como Pascal y C), existe una aproximacin mejor: escribir L traductoo res desde los lenguajes fuente a un lenguaje intermedio y despus escribir M traductores de este e lenguaje intermedio a los lenguajes mquina correspondientes: a
Java Sparc ML PowerPC Pascal Pentium C Alpha C++ C++ C Alpha Pascal L. interm. Pentium ML PowerPC Java Sparc

Esta aproximacin tiene diversas ventajas. La ms obvia es la reduccin del nmero de trao a o u ductores que se necesitarn. Adems, si se quiere aadir un nuevo lenguaje a nuestra coleccin, a a n o no es necesario crear M compiladores para l, basta con un traductor al lenguaje intermedio. Esto e permite que se desarrollen nuevos lenguajes con comodidad. Ms importante, si aparece una nueva a arquitectura, basta con desarrollar un traductor del lenguaje intermedio a esta nueva mquina. a
c Universitat Jaume I 2006-2007

II26 Procesadores de lenguaje

Otro aspecto de gran importancia es que la representacin intermedia suele elegirse de modo o que no necesite el gran nivel de detalle que exige el cdigo mquina y permita abstraer problemas o a como el nmero limitado de registros disponibles o la gran variedad de instrucciones de mquina u a donde elegir. Esto simplica notablemente la generacin de cdigo desde el AST. o o Desgraciadamente, esta aproximacin no es gratis ni universal. Encontrar un lenguaje intermeo dio que sea adecuado para todas las arquitecturas y lenguajes no es tarea sencilla y probablemente no sea posible. En la prctica se emplea para lenguajes similares y mquinas destino que coma a partan una serie de caracter sticas comunes. Por otro lado, determinadas caracter sticas del par (lenguaje fuente, mquina destino) pueden no aprovecharse. Por ejemplo, si sabemos que la ma a quina destino tiene instrucciones especializadas para saltos mediante una tabla, el cdigo generado o para las estructuras switch-case deber reejarlo. Esto no es posible si el lenguaje intermedio a no recoge este tipo de construcciones. Pese a todo, las ventajas superan a los inconvenientes y la generacin de cdigo se divide o o habitualmente en dos etapas: Generacin de cdigo intermedio. o o Generacin de cdigo objeto: se traduce el cdigo intermedio a cdigo de mquina. o o o o a 2.2.1. Generacin de cdigo intermedio o o

En esta etapa se traduce la entrada a una representacin independiente de la mquina pero o a fcilmente traducible a lenguaje ensamblador. Esta representacin puede tomar diversas formas a o que pueden entenderse como visiones idealizadas del lenguaje ensamblador de una mquina virtual. a Algunas de las representaciones ms comunes son: a Arboles de representacin intermedia (distintos de los rboles de sintaxis abstracta), o a cdigo de tres direcciones, o cdigo de dos direcciones, o cdigo de pila, o representaciones en forma de grafo, mixtas, etc. . . En nuestro caso, usando la mquina virtual de las prcticas, la sentencia valor= valor+inc; a a puede traducirse por algo similar a: lw $r0, -2($fp) lw $r1, -1($fp) add $r0, $r0, $r1 sw $r0, -2($fp) 2.2.2. # # # # Carga valor en $r0 Carga inc en $r1 Hace la suma Guarda el resultado en valor

Generacin de cdigo objeto o o

Una vez obtenido el cdigo intermedio, es necesario generar el cdigo objeto. Lo habitual es que o o no se genere el cdigo objeto directamente sino que se genere cdigo en ensamblador y despus se o o e utilice un ensamblador. De cualquier forma, esta fase es totalmente dependiente de la arquitectura concreta para la que se est desarrollando el compilador. En particular, hay que enfrentarse a e problemas como: Seleccin de instrucciones teniendo en cuenta su eciencia. o Eleccin de los modos de direccionamiento adecuados. o Utilizacin eciente de los registros. o Empleo eciente de la cach. e

Estructura de los compiladores e intrpretes e

Otros. . . Las instrucciones que genera gcc para nuestro ejemplo son: movl leal addl -8(%ebp), %edx -4(%ebp), %eax %edx, (%eax)

Como ves, se tiene en cuenta el tamao de las variables (por eso se emplea 4 y 8 en lugar de n 2 y 1), se utilizan registros de la mquina concreta y se emplean instrucciones especiales como a leal para aprovechar mejor el procesador. 2.2.3. Optimizacin o

Tanto a la hora de generar cdigo intermedio como cdigo objeto es habitual encontrarse con o o que el resultado de la traduccin es muy ineciente. Esto es debido a que la traduccin se realiza o o de manera local, lo cual provoca la aparicin de cdigo redundante. Por ejemplo, la sentencia o o a[i]=a[i]+1 genera el siguiente cdigo intermedio: o addi $r0, $zero, 0 lw $r1, 3($zero) add $r0, $r0, $r1 lw $r0, 0($r0) addi $r1, $zero, 1 add $r0, $r0, $r1 addi $r1, $zero, 0 lw $r2, 3($zero) add $r1, $r1, $r2 sw $r0, 0($r1) # # # # # # # # # # Direccin de a o Acceso a i Sumamos i a la direccin de a o Valor de a[i] Valor entero (1) Hacemos la suma Direccin de a o Acceso a i Sumamos i a la direccin de a o Guardamos el resultado

Sin embargo, es fcil darse cuenta de que no hace falta calcular dos veces la direccin de a[i], a o con lo que se pueden ahorrar, al menos, tres instrucciones.
Ejercicio 1

Escribe el cdigo de menor longitud que se te ocurra para el ejemplo anterior. No puedes o utilizar instrucciones distintas de las mostradas. En otras ocasiones, es posible utilizar instrucciones especializadas para mejorar la velocidad. Por ejemplo, si la instruccin anterior a valor= valor+inc; es inc=1;, gcc -O genera o incl %ebx

Por esto, es habitual incluir mdulos encargados tanto de la optimizacin del cdigo intermedio o o o como del cdigo objeto. o

2.3.

Otros mdulos del compilador o

Aunque en principio ser posible escribir el compilador como la concatenacin de las distintas a o fases que se han descrito, existen dos mdulos que no forman parte de esta secuencia pero tienen o un papel fundamental para el proceso de compilacin: la tabla de s o mbolos y el mdulo de gestin o o de errores. 2.3.1. La tabla de s mbolos

A lo largo del proceso de anlisis se va generando gran cantidad de informacin que se puede a o considerar ligada a los objetos que se van descubriendo en el programa: variables, constantes, funciones, etc. El acceso a esta informacin se realiza mediante los nombres de estos objetos. Esto o
c Universitat Jaume I 2006-2007

II26 Procesadores de lenguaje

hace necesario tener alguna manera de, a partir de un identicador, encontrar sus propiedades. La estructura de datos que guarda esta informacin se denomina tabla de s o mbolos y puede interactuar con prcticamente todas las fases de la compilacin. a o Algunos ejemplos de la informacin guardada son: o Constantes: tipo, valor. Variables: tipo, direccin en memoria, tamao. o n Funciones: nmero y tipo de los argumentos, tipo devuelto, direccin. u o Es importante tener en cuenta que la informacin asociada con un identicador puede variar o a lo largo del programa. As por ejemplo, el identicador i se reere a dos variables distintas en , el siguiente cdigo: o
int main() { int i=1; { float i=2.0; printf("%f\n", i); /* i es un float */ } printf("%d\n", i); /* i es un int */ }

Una cuestin de gran importancia ser encontrar una estructura de datos eciente para acceder a o a los elementos de la tabla. 2.3.2. Gestin de errores o

Es un hecho que al programar se cometen errores. Es ms, se puede decir casi con total seguridad a que un compilador encuentra ms programas errneos que correctos. As pues, es importante que a o el compilador ayude en la deteccin y correccin de errores. Para ello, el compilador debe, ante un o o error: Diagnosticarlo de la manera ms clara posible. a Detener la generacin de cdigo. o o Intentar recuperarse para poder continuar el anlisis. a Veremos que, en general, no es posible detectar los errores, slo sus s o ntomas. Por ejemplo, ante la entrada a:= b 1; no es posible saber si falta un + entre la b y el 1 o si sobra un espacio o si sobra el uno. . . Sin embargo, ser posible asegurar que la presencia de un error ha sido detectada a lo antes posible; en nuestro ejemplo, detectaremos el error al ver el 1.

2.4.

Mdulos externos al compilador o

Aunque con lo que hemos visto hasta ahora podr amos considerar que tenemos el compilador completo, hay otros mdulos que tambin se utilizan en el proceso de construccin de prograo e o mas y que en muchos casos son programas independientes invocados por el propio compilador. Comentaremos brevemente tres: el preprocesador, en enlazador y el soporte en ejecucin. o 2.4.1. El preprocesador

En algunos lenguajes (probablemente el ms conocido es C), existe una fase anterior al anlisis a a lxico: el preproceso. En esta fase se realizan acciones tales como expansin de macros o inclusin e o o de cheros. Es interesante darse cuenta de que el preprocesador se comporta como un compilador muy restringido en sus capacidades y que tiene sus propias fases de anlisis y s a ntesis.

Estructura de los compiladores e intrpretes e

2.4.2.

El enlazador

En muchos casos, el resultado de la compilacin no es un programa completo sino una parte o de l: un chero objeto. Una vez se han compilado todas las partes del programa, hay que unirlas, e probablemente tambin empleando alguna biblioteca, para crear el programa nal. El programa e encargado de esto es el enlazador (linker en ingls). e 2.4.3. Soporte en ejecucin o

Adems de las acciones especicadas por el programador, el cdigo nal tiene que hacer una a o serie de acciones necesarias para el buen funcionamiento del programa. La parte aadida al pron grama para hacer esto es lo que se conoce como soporte en ejecucin. Algunas de sus funciones o son preparar la memoria al comienzo de la ejecucin, gestionar la memoria o la pila durante la o ejecucin y preparar la nalizacin de la ejecucin de una manera razonable. Segn los casos, este o o o u cdigo puede estar contenido en funciones de la biblioteca estndar del lenguaje, puede ser aadido o a n al programa o generado automticamente. a

3.

La interpretacin o

Mientras que el objetivo de los compiladores es obtener una traduccin del programa fuente o a otro lenguaje, los intrpretes tienen como objeto la obtencin de los resultados del programa. e o Para ello deben realizar dos tareas: analizar su entrada y llevar a cabo las acciones especicadas por ella. La parte de anlisis puede realizarse de manera idntica a como se lleva a cabo en los compilaa e dores. Es la parte de s ntesis la que se diferencia sustancialmente. En el caso de la interpretacin, o se parte del rbol de sintaxis abstracta y se recorre, junto con los datos de entrada, para obtener a los resultados. En el caso del rbol a asignacin o

idvalor suma idvalor idinc El recorrido consistir en: a Analizar el nodo asignacin. o Visitar su hijo derecho (la suma) para obtener el valor que hay que asignar: Visitar el hijo izquierdo de la suma, recuperar el valor actual de valor. Visitar el hijo derecho de la suma, recuperar el valor actual de inc. Hacer la suma. Guardar el resultado de la suma en valor. Actualmente se est poniendo de moda una especie de h a brido entre la compilacin y la intero pretacin que consiste en compilar a un lenguaje intermedio para una mquina virtual y despus o a e interpretar este lenguaje. Esta aproximacin es la que se sigue, por ejemplo, en Java, Python o la o plataforma .NET.
c Universitat Jaume I 2006-2007

II26 Procesadores de lenguaje

4.

La arquitectura real de compiladores e intrpretes e

Siguiendo la descripcin de las fases hecha ms arriba, vemos que la estructura de un compilador o a es similar a la siguiente:
Programa fuente Anlisis a Anlisis a lxico e Anlisis a sintctico a Anlisis a semntico a

Arbol de sintaxis abstracta S ntesis Generacin de o cdigo intermedio o Optimizacin de o cdigo intermedio o Generacin de o cdigo objeto o Optimizacin de o cdigo objeto o

Programa objeto

De manera anloga, un intrprete tendr esta estructura: a e a


Programa fuente Anlisis a Anlisis a lxico e Anlisis a sintctico a Anlisis a semntico a

Arbol de sintaxis abstracta S ntesis Generacin de o resultados

Resultados

O, si utilizramos una mquina virtual, el intrprete tendr esta estructura: a a e a


Programa fuente Anlisis a Anlisis a lxico e Anlisis a sintctico a Anlisis a semntico a

Arbol de sintaxis abstracta S ntesis Generacin de o cdigo intermedio o Optimizacin de o cdigo intermedio o Intrprete de e mquina virtual a

Resultados

Estructura de los compiladores e intrpretes e

Sin embargo, en la prctica, la separacin entre las distintas fases no est tan marcada. Lo a o a habitual es que el analizador sintctico haga las veces de maestro de ceremonias, pidiendo al a analizador lxico los componentos lxicos a medida que los va necesitando y pasando al analizador e e semntico la informacin que va obteniendo. De hecho, lo ms normal es que este ultimo (el a o a analizador semntico) no exista como un mdulo separado sino que est integrado en el sintctico. a o e a As se elimina la necesidad de crear un arbol de anlisis. Esta organizacin suele llamarse traduccin a o o dirigida por la sintaxis. Si la memoria disponible es escasa, puede resultar imposible mantener una representacin de o todo el programa. En estos casos, se unen las fases de anlisis y de s a ntesis. De esta manera, se va generando cdigo al mismo tiempo que se analiza el programa fuente. Esta forma de trabajar era o habitual en compiladores ms antiguos y exige ciertas caracter a sticas especiales al lenguaje, como las declaraciones forward de Pascal.

5.

Algunos conceptos de teor de lenguajes formales a

Al comentar las distintas fases del compilador, hemos mencionado la existencia de herramientas formales para la especicacin de los analizadores lxico (lenguajes regulares) y sintctico (lenguao e a jes incontextuales). Ambos tipos de herramientas se incluyen dentro de la teor de los lenguajes a formales. Ahora veremos una introduccin a esta teor o a.

5.1.

Conceptos bsicos a

Un alfabeto es un conjunto nito de s mbolos. No nos interesa la naturaleza de los s mbolos. Dependiendo de la aplicacin que tengamos en mente, stos pueden ser: caracteres, como al espeo e cicar el analizador lxico; letras o palabras, si queremos trabajar con lenguaje natural; categor e as lxicas, al especicar el analizador sintctico; direcciones en el plano, al hacer OCR; . . . e a Una cadena es una secuencia nita de s mbolos del alfabeto. Nuevamente, no estamos interesados en la naturaleza precisa de las cadenas. Si estamos especicando el analizador lxico, podemos e ver la entrada como una cadena; si trabajamos con lenguaje natural, la cadena puede ser una pregunta a una base de datos; para el analizador sintctico, una cadena es el programa una vez a pasado por el analizador lxico; en OCR, una cadena es la descripcin de una letra manuscrita;. . . e o La cadena de longitud cero se denomina cadena vac y se denota con . Para referirnos al a conjunto de cadenas de longitud k, utilizamos k . Si nos referimos al conjunto de todas las cadenas, la clausura del alfabeto, escribimos:

=
k=0

k = 0 1 2 . . .

La clausura positiva incluye todas las cadenas excepto la vac a:

+ = {} =
k=1

k = 1 2 3 . . .

F jate que tanto como + son conjuntos innitos de cadenas nitas. Un lenguaje formal es un subconjunto de . Date cuenta que no entramos en si es nito o innito. Tampoco en este caso esperamos que el lenguaje tenga relacin alguna con los lenguajes o humanos o que sus cadenas tengan signicado alguno; un lenguaje formal es simplemente un conjunto de cadenas.

5.2.

Gramticas a

Tenemos ahora un pequeo problema. Los lenguajes pueden ser innitos, pero deseamos desn cribirlos utilizando un tiempo y unos recursos nitos (una descripcin innita probablemente ser o a
c Universitat Jaume I 2006-2007

10

II26 Procesadores de lenguaje

demasiado larga para este curso). Existen diversas maneras para describir lenguajes, aqu recor daremos las gramticas formales. a Qu es una gramtica formal? Simplemente una cudrupla (N, , P, S ) donde e a a N es un alfabeto de no terminales. es un alfabeto de terminales, disjunto con N . P (N ) N (N ) (N ) es un conjunto de producciones o reglas. S es el s mbolo inicial (pertenece a N ). Por comodidad, las producciones se representan como si (, ) P .

Convenios de notacin o En lo sucesivo y con objeto de no tener que indicar expl citamente a qu alfabeto (N o ) pertee nece cada s mbolo o cadena, asumiremos unos convenios notacionales que permitirn deducirlo a inmediatamente: Representamos los terminales con un tipo de letra mecanogrco (a, c, +, :=), en negrita a (identicador, entero) o entrecomillado (|, <). Los no terminales se representan encerrados entre ngulos ( A , Programa ). a Un s mbolo que puede ser terminal o no terminal, indistintamente, se representar a con alguna de las ultimas letras maysculas del alfabeto latino (X, Y,. . . ). u La cadenas de s mbolos terminales (elementos de ) se representan con la ultimas letras minsculas del alfabeto latino (u, v, w,. . . ). u Las cadenas de s mbolos terminales o no terminales (elementos de (N ) ) se representan con letras minsculas del alfabeto griego (, , ,. . . ). u

5.2.1.

Cmo funcionan las gramticas? o a

El funcionamiento de las gramticas se basa en el concepto de derivacin. Comenzando por una a o cadena formada unicamente por el s mbolo inicial, se aplican repetidamente las reglas de P hasta llegar a una cadena formada unicamente por terminales. Aplicar una regla consiste simplemente en encontrar, dentro de la cadena actual, la parte izquierda de la regla y sustituirla por la parte derecha. Por ejemplo, sea la gramtica: G = ({ S , E }, {id, +, *}, P, S ), con a P = {S E, E E+E, E E*E, E id}; para derivar id+id*id podemos hacer: S E E+E E+E*E id+ E * E id+id* E id+id*id

Estructura de los compiladores e intrpretes e

11

Ejercicio 2

Encuentra otra derivacin de id+id*id. o


Ejercicio* 3

Cuntas derivaciones distintas tiene la cadena id+id*id? a De una manera ms formal, tenemos las siguientes deniciones: a Derivacin directa: deriva directamente en G si = 1 2 , = 1 2 y P . Lo o denotamos con . Derivacin: deriva (en G) si hay una secuencia de cadenas (1 , 2 , . . . , n ) de (N ) tal o que = 1 , = n y i i+1 para 1 i < n. Lo denotamos con . Forma sentencial: Cadena de (N ) tal que S . Sentencia: forma sentencial perteneciente a . Lenguaje denido (o generado) por la gramtica G: L(G) = {x | S x}. a
Ejercicio 4

Cul es el lenguaje denido por la gramtica del ejemplo anterior? a a

5.3.

La jerarqu de Chomsky a

Podemos ordenar jerrquicamente las gramticas en funcin de su potencia por la forma a a o de sus producciones: Gramtica de tipo 0 o no restringida: producciones de la forma , donde (N a ) N (N ) y (N ) . Gramtica de tipo 1 o sensible al contexto: producciones de la forma A , donde a , (N ) , (N )+ , A N . Gramtica de tipo 2 o incontextual : producciones de la forma A , donde A N y a (N ) . Gramtica de tipo 3 o regular : producciones de la forma A a B , A a A , a o donde A , B N y a . Tambin clasicamos los lenguajes por su tipo: un lenguaje es del tipo i si existe una gramtica de e a ese tipo capaz de generarlo. Las gramticas de tipo 0 son las que poseen mayor poder descriptivo, a y las de tipo 3 las de menor: as un lenguaje de tipo 3 tambin es de tipo 2, un lenguaje de tipo 2 e que no incluya la cadena vac es de tipo 1 y todo lenguaje de tipo 1 es tambin de tipo 0. Por a e lo general, diremos que el tipo de un lenguaje es el tipo de la gramtica ms restringida capaz de a a generarlo.
Ejercicio 5

De qu tipo son los siguientes lenguajes? e Las cadenas de bits con un nmero par de unos. u Las cadenas de bits que representan un mltipo de tres. u Las cadenas de bits pal ndromas. Las cadenas de bits con ms ceros que unos. a Las cadenas de bits que representan un cuadrado perfecto.

c Universitat Jaume I 2006-2007

12

II26 Procesadores de lenguaje

5.4.

Dos convenios ms a

Para simplicar la exposicin, adoptaremos dos convenios adicionales. A la hora de escribir o una gramtica, slo mostraremos las reglas y asumiremos que el s a o mbolo inicial es el que est a la a parte izquierda de la primera regla. Tambin asumiremos que la gramtica no tiene ni s e a mbolos intiles ni reglas intiles. Esto u u es, para cada s mbolo o regla, habr al menos una derivacin de una sentencia del lenguaje que a o contenga ese s mbolo o regla.

5.5.

Anlisis sintctico a a

Tal como las hemos visto, las gramticas son dispositivos generativos, es decir, nos dan un ma e todo para obtener todas las cadenas del lenguaje. Sin embargo, al plantearnos hacer un compilador o un intrprete, el problema al que nos enfrentamos es el inverso: e Dada una cadena x y una gramtica G, pertenece x a L(G)? a F jate que, si x pertenece al lenguaje de G, existe al menos una derivacin de x en G. Nos interesar o a saber cul es esa derivacin (o derivaciones), puesto que ser lo que nos indique la estructura a o a de x. Siguiendo la clasicacin de las gramticas, podemos asignar a cada tipo un dispositivo capaz o a de reconocer sus cadenas: Tipo de lenguaje Regular Incontextual Sensible al contexto No restringido Dispositivo reconocedor Autmata de estados nitos o Autmata de pila o Autmata de memoria limitada linealmente o Mquina de Turing a

Estos dispositivos son slo mquinas virtuales. En la prctica, tienen que ser emulados por o a a programas. En el caso de los lenguajes regulares, se puede analizar la pertenencia de una cadena x a un lenguaje en tiempo O(|x|). En el caso de los lenguajes incontextuales, se necesita O(|x|3 ). Dado que esto es muy costoso, utilizaremos restricciones de los lenguajes incontextuales que permiten el anlisis con un coste lineal. a

5.6.

Lenguajes formales y compiladores

La divisin que hemos hecho del problema del anlisis nos permite utilizar gramticas regulares o a a para el analizador lxico y gramticas incontextuales para el sintctico. En principio, se podr e a a an utilizar gramticas sensibles al contexto para especicar las restricciones semnticas. Sin embargo, a a la complejidad de la escritura de estas gramticas y el elevado coste temporal de los algoritmos de a anlisis aconsejan que las restricciones se escriban utilizando como formalismo las gramticas atria a buidas. Estas pueden verse como gramticas incontextuales enriquecidas para admitir fragmentos a de cdigo. o Es muy importante darse cuenta de cules son los alfabetos sobre los que se denen los lenguajes a empleados en el analizador lxico y sintctico. El analizador lxico dene lenguajes sobre el alfabeto e a e de los caracteres de la mquina. As sern lenguajes sobre los juegos de caracteres ASCII, ISOlatin, a a EBCDIC, Unicode, etc. El anlisis sintctico dene lenguajes sobre el conjunto de las categor a a as lxicas, ya que son lo que ve el analizador sintctico. e a

6.

Resumen del tema


Dos etapas en la traduccin: anlisis y s o a ntesis. Anlisis: a

Estructura de los compiladores e intrpretes e

13

Lxico: de caracteres a componentes. e Sintctico: de componentes a rboles de anlisis. a a a Semntico: de rboles de anlisis a AST. a a a S ntesis: En compilacin: o Generacin de cdigo intermedio. o o Generacin de cdigo objeto. o o Optimizacin (mezclada con las anteriores). o En interpretacin, dos opciones: o Generacin de cdigo intermedio e interpretacin del cdigo intermedio. o o o o Generacin de resultados. o Lenguajes formales: conjuntos de cadenas sobre un alfabeto. Especicacin de lenguajes: mediante gramticas. o a Usaremos: Anlisis lxico: lenguajes regulares. a e Anlisis sintctico: lenguajes incontextuales. a a

c Universitat Jaume I 2006-2007

You might also like