Compi Usach

156
Universidad de Santiago de Chile Facultad de Ingeniería Departamento de Ingeniería Informática APUNTES DE LA ASIGNATURA COMPILADORES Mag. Jacqueline Köhler C.

description

Apunte sobre teoría de compiladores

Transcript of Compi Usach

  • Universidad de Santiago de Chile Facultad de Ingeniera Departamento de Ingeniera Informtica

    APUNTES DE LA ASIGNATURA

    COMPILADORES

    Mag. Jacqueline Khler C.

  • 2

    Compiladores

    Jacqueline Khler C. - USACH

    TABLA DE CONTENIDOS 1 INTRODUCCIN ................................................................................................................................. 7

    1.1 QU ES UN PROGRAMA? ......................................................................................................... 8

    1.2 DEFINICIN DE COMPILADOR ................................................................................................ 8

    1.3 COMPILADORES E INTRPRETES ........................................................................................... 9

    1.4 CONTEXTO EN QUE SE SITA EL COMPILADOR ................................................................ 9

    1.5 FASES DE UN COMPILADOR .................................................................................................. 11

    1.6 CLASIFICACIN DE LOS COMPILADORES.......................................................................... 13

    1.7 HERRAMIENTAS TILES ......................................................................................................... 13

    2 ANLISIS LXICO ............................................................................................................................ 14

    2.1 FUNCIN DEL ANALIZADOR LXICO.................................................................................. 14

    2.2 COMPONENTES LXICOS, PATRONES Y LEXEMAS ......................................................... 15

    2.3 ERRORES LXICOS ................................................................................................................... 16

    2.4 IMPLEMENTACIN DE ANALIZADORES LXICOS .......................................................... 17

    2.4.1 MTODOS GENERALES ..................................................................................................... 17

    2.4.2 CONSTRUCCIN DE UN ANALIZADOR LXICO ......................................................... 17

    2.5 EJERCICIOS ................................................................................................................................. 21

    3. ANLISIS SINTCTICO .................................................................................................................. 23

    3.1 CONCEPTOS PREVIOS .............................................................................................................. 23

    3.1.1 RECURSIVIDAD POR LA IZQUIERDA ............................................................................. 23

    3.1.2 FACTORIZACIN POR LA IZQUIERDA .......................................................................... 24

    3.1.3 CONJUNTOS ANULABLE, PRIMERO Y SIGUIENTE ..................................................... 27

    3.1.3.1 Conjunto Anulable ........................................................................................................... 27

    3.1.3.2 Conjunto Primero ............................................................................................................. 27

    3.1.3.3 Conjunto Siguiente ........................................................................................................... 27

    3.2 DESCRIPCIN GENERAL DEL ANLISIS SINTCTICO .................................................... 28

    3.3 ALGUNOS ASPECTOS DEL MANEJO DE ERRORES SINTCTICOS................................. 29

    3.4 ANLISIS SINTCTICO PREDICTIVO ................................................................................... 30

    3.4.1 ASPECTOS GENERALES .................................................................................................... 30

    3.4.2 CONSTRUCCIN Y FUNCIONAMIENTO DE ANALIZADORES SINTCTICOS LL(1) ......................................................................................................................................................... 31

  • 3

    Compiladores

    Jacqueline Khler C. - USACH

    3.4.3 GRAMTICAS LL(1) ........................................................................................................... 35

    3.4.4 RECUPERACIN DE ERRORES EN ANLISIS SINTCTICO LL(1) ........................... 35

    3.4.4.1 Recuperacin de errores en modo de pnico ................................................................... 35

    3.4.4.2 Recuperacin de errores a nivel de frase ......................................................................... 36

    3.5 ANLISIS SINTCTICO DESCENDENTE (POR DESPLAZAMIENTO Y REDUCCIN) .. 37

    3.5.1 ASPECTOS GENERALES .................................................................................................... 37

    3.5.2 GRAMTICAS LR(K) .......................................................................................................... 38

    3.5.3 ANLISIS SINTCTICO SLR ............................................................................................. 38

    3.5.3.1 Elemento LR(0)................................................................................................................ 38

    3.5.3.2 Operacin Clausura .......................................................................................................... 39

    3.5.3.3 Construccin del autmata ............................................................................................... 40

    3.5.3.4 Construccin y operacin del analizador sintctico SLR ................................................ 42

    3.5.4 USO DE GRAMTICAS AMBIGUAS ................................................................................ 48

    3.5.5 RECUPERACIN DE ERRORES ........................................................................................ 49

    3.5.5.1 Recuperacin en modo de pnico .................................................................................... 49

    3.5.5.2 Recuperacin a nivel de frase .......................................................................................... 50

    3.5.6 ANLISIS SINTCTICO LR(1) ........................................................................................... 51

    3.5.6.1 Elemento LR(1)................................................................................................................ 51

    3.5.6.2 Operacin clausura ........................................................................................................... 52

    3.5.6.3 Construccin del AFD ..................................................................................................... 53

    3.5.6.4 Construccin de la tabla de anlisis sintctico LR(1) ...................................................... 53

    3.5.7 ANLISIS SINTCTICO LALR .......................................................................................... 58

    3.5.7.1 Notas preliminares ........................................................................................................... 58

    3.5.7.2 Construccin del AFD a partir del analizador sintctico LR(1) ...................................... 58

    3.5.7.3 Construccin directa del AFD.......................................................................................... 63

    3.6 EJERCICIOS ................................................................................................................................. 64

    4 ANLISIS SEMNTICO ................................................................................................................... 66

    4.1 DEFINICIONES DIRIGIDAS POR LA SINTAXIS .................................................................... 66

    4.1.1 ATRIBUTOS SINTETIZADOS ............................................................................................ 67

    4.1.2 ATRIBUTOS HEREDADOS ................................................................................................. 68

    4.1.3 GRAFOS DE DEPENDENCIAS ........................................................................................... 69

  • 4

    Compiladores

    Jacqueline Khler C. - USACH

    4.2 RBOLES SINTCTICOS .......................................................................................................... 71

    4.3 COMPROBACIN DE TIPOS .................................................................................................... 72

    4.4 OTRAS COMPROBACIONES SEMNTICAS ......................................................................... 76

    4.4.1 VALORES DEL LADO IZQUIERDO .................................................................................. 76

    4.4.2 PARMETROS DE FUNCIN ............................................................................................ 77

    4.4.3 PALABRA CLAVE return ..................................................................................................... 78

    4.4.4 CASOS DUPLICADOS EN UN switch................................................................................. 79

    4.4.5 ETIQUETAS goto .................................................................................................................. 79

    4.5 EJERCICOS .................................................................................................................................. 79

    5 AMBIENTES PARA EL MOMENTO DE EJECUCIN .................................................................. 82

    5.1 ASPECTOS DEL LENGUAJE FUENTE .................................................................................... 82

    5.1.1 PROCEDIMIENTOS ............................................................................................................. 82

    5.1.2 RBOLES DE ACTIVACIN .............................................................................................. 82

    5.1.3 PILAS DE CONTROL ........................................................................................................... 83

    5.1.4 MBITO DE UNA DECLARACIN ................................................................................... 85

    5.1.5 ENLACE DE NOMBRES ...................................................................................................... 85

    5.2 ORGANIZACIN DE LA MEMORIA ....................................................................................... 86

    5.2.1 SUBDIVISIN DE LA MEMORIA DURANTE LA EJECUCIN ..................................... 86

    5.2.2 REGISTROS DE ACTIVACIN .......................................................................................... 86

    5.2.3 DISPOSICIN ESPACIAL DE LOS DATOS LOCALES EN EL MOMENTO DE LA COMPILACIN.............................................................................................................................. 87

    5.3 ESTRATEGIAS PARA LA ASIGNACIN DE MEMORIA ..................................................... 88

    5.3.1 ASIGNACIN ESTTICA ................................................................................................... 88

    5.3.2 ASIGNACIN POR MEDIO DE UNA PILA ....................................................................... 89

    5.3.3 ASIGNACIN POR MEDIO DE UN MONTCULO .......................................................... 89

    5.4 ACCESO A NOMBRES NO LOCALES ..................................................................................... 89

    5.4.1 BLOQUES .............................................................................................................................. 90

    5.4.2 MBITO LXICO SIN PROCEDIMIENTOS ANIDADOS ................................................ 91

    5.4.3 MBITO LXICO CON PROCEDIMIENTOS ANIDADOS .............................................. 92

    5.4.4 MBITO DINMICO ........................................................................................................... 92

    5.5 PASO DE PARMETROS .......................................................................................................... 93

  • 5

    Compiladores

    Jacqueline Khler C. - USACH

    5.5.1 LLAMADA POR VALOR ..................................................................................................... 94

    5.5.2 LLAMADA POR REFERENCIA .......................................................................................... 95

    5.5.3 COPIA Y RESTAURACIN................................................................................................. 95

    5.6 TABLA DE SMBOLOS .............................................................................................................. 96

    5.6.1 ENTRADAS DE LA TABLA DE SMBOLOS .................................................................... 97

    5.6.2 INFORMACIN SOBRE LA ASIGNACIN DE MEMORIA ........................................... 97

    5.6.3 TIPOS DE TABLAS DE SMBOLOS ................................................................................... 98

    5.6.4 IMPLEMENTACIN DE LA TABLA DE SMBOLOS ...................................................... 98

    5.6.5 REPRESENTACIN DE LA INFORMACIN SOBRE EL MBITO ............................... 99

    5.7 ASIGNACIN DINMICA DE LA MEMORIA ...................................................................... 101

    5.7.1 INSTRUMENTOS DE LOS LENGUAJES ......................................................................... 101

    5.7.2 ASIGNACIN EXPLCITA DE BLOQUES DE TAMAO FIJO .................................... 102

    5.7.3 ASIGNACIN EXPLCITA DE BLOQUES DE TAMAO VARIABLE ........................ 102

    5.7.4 DESASIGNACIN IMPLCITA ......................................................................................... 103

    5.7.4.1 Cuenta de referencias ..................................................................................................... 104

    5.7.4.2 Tcnicas de marca .......................................................................................................... 104

    5.8 EJERCICIOS ............................................................................................................................... 104

    6 GENERACIN DE CDIGO INTERMEDIO ................................................................................. 106

    6.1 LENGUAJES INTERMEDIOS .................................................................................................. 106

    6.1.1 REPRESENTACIONES GRFICAS .................................................................................. 106

    6.1.2 CDIGO DE TRES DIRECCIONES .................................................................................. 107

    6.1.2.1 Tipos de proposiciones de tres direcciones .................................................................... 108

    6.1.2.2 Implementaciones de cdigo de tres direcciones ........................................................... 109

    6.1.2.3.1 Cudruplos............................................................................................................... 109

    6.1.2.3.2 Triples ...................................................................................................................... 110

    6.1.2.3.3 Triples indirectos ..................................................................................................... 110

    6.2 TRADUCCIN DIRIGIDA POR LA SINTAXIS ..................................................................... 111

    6.2.1 DECLARACIONES ............................................................................................................. 111

    6.2.1.1 Declaraciones dentro de un procedimiento .................................................................... 112

    6.2.1.2 Nombres de campos dentro de registros ........................................................................ 114

    6.2.3 PROPOSICIONES DE ASIGNACIN ............................................................................... 114

  • 6

    Compiladores

    Jacqueline Khler C. - USACH

    6.2.3.1 Expresiones aritmticas .................................................................................................. 115

    6.2.3.2 Expresiones booleanas ................................................................................................... 117

    6.2.3.3 Acceso a elementos de matrices ..................................................................................... 119

    6.2.3.4 Acceso a elementos de registros .................................................................................... 121

    6.2.4 SENTENCIAS DE FLUJO DE CONTROL ........................................................................ 121

    6.2.4.1 Sentencia goto ................................................................................................................ 121

    6.2.4.2 Sentencia if ..................................................................................................................... 121

    6.2.4.3 Sentencia if-else ............................................................................................................. 122

    6.2.4.4 Sentencia switch ............................................................................................................. 123

    6.2.4.5 Sentencia while .............................................................................................................. 124

    6.2.4.6 Sentencia do-while ......................................................................................................... 125

    6.2.4.7 Sentencia repeat-until ..................................................................................................... 126

    6.2.4.8 Sentencia for .................................................................................................................. 126

    6.2.5 LLAMADAS A PROCEDIMIENTOS ................................................................................ 127

    6.3 EJERCICIOS ............................................................................................................................... 127

    BIBLIOGRAFA .................................................................................................................................. 129

    ANEXO: NOCIONES DE LENGUAJES FORMALES ...................................................................... 130

    A.1 JERARQUA DE LOS LENGUAJES ....................................................................................... 130

    A.2 GRAMTICAS .......................................................................................................................... 131

    A.2.1 GRAMTICAS REGULARES .......................................................................................... 135

    A.2.2 GRAMTICAS LIBRES DE CONTEXTO ....................................................................... 136

    A.2 EXPRESIONES REGULARES ................................................................................................. 138

    A.3 AUTMATAS FINITOS ........................................................................................................... 139

    A.3.1 AUTMATA FINITO DETERMINSTICO (AFD) .......................................................... 141

    A.3.2 AUTMATA FINITO NO DETERMINSTICO (AFND)................................................. 144

    A.3.3 EQUIVALENCIA ENTRE AFD Y AFND ......................................................................... 145

    A.3.4 MINIMIZACIN DE AFD ................................................................................................. 148

    A.3.5 EQUIVALENCIA ENTRE AF Y ER: MTODO DE THOMPSON ................................. 149

    A.4 AUTMATAS APILADORES ................................................................................................. 153

  • 7

    Compiladores

    Jacqueline Khler C. - USACH

    1 INTRODUCCIN Un lenguaje es una abstraccin que permite la comunicacin y coordinacin mediante la creacin de conceptos que pueden ser entendidos de la misma forma por los distintos participantes. As, un lenguaje puede entenderse como una forma de hablar o de describir algo. Para poder hablar de lenguaje es importante conocer algunos elementos. Por ejemplo, cmo se crean los conceptos? Cmo hacer que todos entiendan lo mismo? El primer paso para responder esta pregunta est en el concepto de smbolo. En el caso del castellano, se puede pensar en las letras como smbolos elementales, que se emplean para construir conceptos sencillos denominados palabras. El conjunto de todos los smbolos se conoce como alfabeto. Ahora bien, las palabras tambin pueden formar parte de estructuras ms complejas: frases y oraciones. A su vez, stas pueden conformar prrafos, etc. A partir de los conceptos anteriores podra pensarse que cualquier secuencia de letras es una palabra o que una oracin podra ser una secuencia aleatoria de palabras. Pero de nuestra experiencia previa sabemos que no es as. Existe una serie de reglas que limitan la forma de las palabras o la estructura de un texto: Reglas lxicas: corresponden a las reglas de ortografa de un lenguaje, e indican la forma que deben

    tener las palabras. Por ejemplo, en castellano no puede haber palabras que contengan una n seguida de una b.

    Reglas sintcticas: definen la forma en que se debe estructurar un texto. Por ejemplo, una oracin debe tener sujeto y predicado. El predicado debe tener un ncleo que puede ir acompaado de diversos complementos.

    Reglas semnticas: determinan el significado de lo que se dice en el texto sintcticamente correcto y guardan relacin con el contexto. Por ejemplo, la frase se rbol puede referirse a un rbol de un parque, o bien a una estructura de datos empleada en la resolucin de un problema computacional.

    Con todo lo anterior, ya tenemos una primera nocin de qu es un lenguaje. Ahora bien, sabemos que existen muchos lenguajes y que en ocasiones es necesario pasar un mensaje o texto de un lenguaje a otro. De aqu surgen los conceptos de traduccin (generar una copia escrita del mensaje original en un idioma distinto) e interpretacin (repetir verbalmente un mensaje en un lenguaje diferente al empleado por el emisor). Existen diferentes tipos de lenguajes. Por ahora, nos basta distinguir entre: Lenguajes naturales: son aquellos que las personas utilizan para comunicarse entre ellas, como el

    castellano, el ingls o el chino. Son muy complejos, tienen una gran cantidad de reglas y sin embargo presentan situaciones de ambigedad que los hablantes resuelven recurriendo al contexto tanto de espacio como de tiempo.

    Lenguajes formales: son lenguajes artificiales, diseados para lograr una comunicacin (unidireccional) entre personas y mquinas. Estas ltimas deben comprender los mensajes y ejecutarlos, por lo que las reglas de los lenguajes formales deben estar muy bien definidas y no pueden dar lugar a ambigedades.

  • 8

    Compiladores

    Jacqueline Khler C. - USACH

    En ciencias de la computacin, el estudio de los lenguajes formales se limita a sus caractersticas intrnsecas e internas, sin tener en cuenta su significado ni su uso como herramienta de comunicacin, puesto que esto ltimo corresponde a una atribucin asignada por un observador externo al lenguaje. En este curso daremos respuesta a una pregunta que se desprende de todo lo expuesto anteriormente: cmo aplicar la teora de lenguajes formales para poder comunicarnos con las mquinas? 1.1 QU ES UN PROGRAMA? En cursos anteriores siempre hemos pensado en un programa como una secuencia estructurada de sentencias escritas en algn lenguaje y que son ejecutadas por un computador para resolver un problema. Sin embargo, antes de comenzar a hablar de compiladores tenemos que definir qu es un programa desde otra perspectiva: como una cadena de caracteres construida sobre un alfabeto determinado (habitualmente ASCII o un subconjunto de l) y almacenada en un archivo. En otras palabras, un programa es una palabra del lenguaje, generalmente un lenguaje libre de contexto. Sin embargo, tambin podemos considerar que esta gran palabra contiene subsecuencias que, a su vez, son palabras pertenecientes a lenguajes ms sencillos que conforman las denominadas categoras lxicas. Cada una de estas categoras puede ser definida por un lenguaje ms sencillo (casi siempre un lenguaje regular) y da origen a un tipo especfico de palabras. Entre los ms habituales podemos encontrar, por ejemplo: Identificadores predefinidos para elementos propios del lenguaje (palabras reservadas, operadores,

    etc.). Identificadores definidos por el programador. Representacin literal de valores. Delimitadores. Comentarios. 1.2 DEFINICIN DE COMPILADOR Para comenzar con la definicin de compilador, lo primero que hay que tener en cuenta es que un compilador es un programa. Su funcin consiste en leer otro programa, denominado programa fuente y escrito en un lenguaje llamado lenguaje fuente, para posteriormente traducirlo a un programa equivalente (programa objeto) escrito en un segundo lenguaje denominado lenguaje objeto (ver figura 1.1). Adems, antes de efectuar la traduccin comprueba que el programa fuente est correctamente escrito e informa al usuario en caso de encontrar errores.

    Existe una gran diversidad de lenguajes fuente, que van desde los ms populares (Java, C/C++, Visual Basic, etc.) hasta aquellos altamente especializados. De igual manera existen muchos lenguajes objeto, que abarcan desde el lenguaje de mquina de cualquier computador hasta otros lenguajes de programacin. No es difcil imaginar que la tarea de convertir un programa fuente escrito en un lenguaje de alto nivel en un programa objeto cuyo lenguaje podra ser el de la mquina en que ser ejecutado no es sencilla.

  • 9

    Compiladores

    Jacqueline Khler C. - USACH

    En consecuencia, tampoco es sencillo escribir un buen compilador. Para ello se requieren conocimientos en diferentes reas: lenguajes de programacin, arquitectura de computadores, teora de lenguajes, algoritmos e ingeniera de software. En este curso solo nos centraremos en la teora de lenguajes. Pero, para qu hacer esta traduccin? Aho et al. afirman que: el 90 % del tiempo de ejecucin de un programa se encuentra en el 10 % del mismo. En consecuencia, una de las grandes ventajas de usar un compilador es la optimizacin de cdigo que realizan. Dichas optimizaciones no solo se traducen en un menor tiempo de ejecucin, sino tambin en una reduccin del consumo de energa por parte del procesador y en una menor cantidad de accesos a memoria.

    FIGURA 1.1: Representacin bsica de un compilador. 1.3 COMPILADORES E INTRPRETES Ahora que ya tenemos una primera definicin para el trmino compilador es posible destacar la gran diferencia que existe entre un compilador y un intrprete. Se seal anteriormente que el primero genera un programa equivalente al programa fuente, pero escrito en el lenguaje objeto. El intrprete, en cambio, toma una sentencia del programa fuente, la traduce al lenguaje objeto y la ejecuta, pero no guarda una copia de la traduccin. As pues, podemos asociar la idea de la compilacin a la traduccin de un texto escrito, en la que generamos un documento equivalente escrito en otro idioma. En cambio, la nocin de interpretacin se asemeja a la traduccin simultnea que se realiza en conferencias o eventos deportivos, en que una persona transmite un mensaje en forma verbal y otra emite un mensaje equivalente en otra lengua. La tabla 1.1 muestra las ventajas que ofrecen la compilacin y la interpretacin, respectivamente. 1.4 CONTEXTO EN QUE SE SITA EL COMPILADOR Muchas veces no basta con un compilador para obtener un programa objeto ejecutable. Por ejemplo, un programa fuente podra estar dividido en mdulos almacenados en diferentes archivos. La tarea de reunir los diversos fragmentos del programa fuente a menudo se confa a un programa distinto, llamado preprocesador, el cual puede tambin expandir abreviaturas, llamadas macros y a proposiciones del lenguaje fuente. El programa objeto creado por el compilador puede requerir procesamiento adicional para poder ser ejecutado. La figura 1.2 muestra, a modo de ejemplo, un compilador que crea cdigo en lenguaje

  • 10

    Compiladores

    Jacqueline Khler C. - USACH

    ensamblador, el cual debe ser traducido a cdigo de mquina por un ensamblador y luego enlazado a algunas rutinas de biblioteca para finalmente generar el cdigo que podr ser ejecutado en la mquina.

    Ventajas de compilar Ventajas de interpretar Se compila una vez y se ejecuta muchas veces.

    Un intrprete requiere menos memoria que un compilador.

    La ejecucin del programa objeto es mucho ms rpida que la interpretacin del programa fuente.

    Permite mayor interaccin con el cdigo en tiempo de desarrollo.

    El compilador tiene una visin ms detallada del programa, por lo que la informacin de los mensajes de error es ms detallada.

    En algunos lenguajes incluso es posible aadir cdigo mientas otra parte del cdigo se est ejecutando (Smalltalk, Prolog, LISP).

    Al usar lenguajes interpretados se tiene una mayor portabilidad.

    TABLA 1.1: Ventajas de compilar e interpretar.

    El lenguaje ensamblador es una versin mnemotcnica del lenguaje de mquina, donde se usan nombres para las operaciones en lugar de cdigos binarios y tambin se usan nombres para las direcciones de memoria. Adems, un ensamblador es un compilador cuyo lenguaje fuente es el lenguaje ensamblador.

    FIGURA 1.2: Sistema para procesamiento de un lenguaje.

  • 11

    Compiladores

    Jacqueline Khler C. - USACH

    Algunos elementos nuevos que aparecen en la figura 1.2 son: 1. Cdigo de mquina relocalizable: es cdigo que puede cargarse empezando en cualquier posicin

    L de la memoria. Es decir, si se suma L a todas las direcciones del cdigo, entonces todas las referencias sern correctas.

    2. Proceso de carga: consiste en tomar el cdigo de mquina relocalizable, modificar las direcciones de memoria y colocar las instrucciones y los datos modificados en las posiciones apropiadas de la memoria.

    3. Editor de enlace: permite formar un nico programa a partir de varios archivos de cdigo de

    mquina relocalizable. 1.5 FASES DE UN COMPILADOR Antes de comenzar la descripcin de las diferentes etapas del proceso de compilacin, puede resultar esclarecedor el modelo que separa estas etapas en dos grandes bloques: anlisis y sntesis (figura 1.3).

    FIGURA 1.3: Modelo de anlisis y sntesis de la compilacin.

    El anlisis separa al programa fuente en los diversos componentes lxicos (tokens) que lo componen y luego crea una representacin intermedia. Posteriormente la sntesis se sirve de la representacin intermedia generada durante el anlisis para construir el programa objeto.

    La figura 1.4 muestra las distintas fases de un compilador, donde las primeras cuatro etapas que recorre el programa fuente constituyen el anlisis y las siguientes, la sntesis. A continuacin se describen brevemente las diferentes etapas: 1. Anlisis lxico: lee, de izquierda a derecha, la cadena de caracteres que constituye el programa

    fuente y la agrupa en componentes lxicos, que son secuencias de caracteres que tienen un significado colectivo. Normalmente durante esta etapa se eliminan los espacios en blanco y los comentarios.

    2. Anlisis sintctico: agrupa los componentes lxicos del programa fuente en frases gramaticales que el compilador utiliza para sintetizar la salida.

    3. Anlisis semntico: se revisan las frases gramaticales que conforman el programa para detectar errores semnticos, es decir, que guarden relacin con el significado de los elementos, y rene la

  • 12

    Compiladores

    Jacqueline Khler C. - USACH

    informacin sobre los tipos para la posterior fase de generacin de cdigo. El anlisis semntico utiliza la estructura jerrquica determinada por la fase de anlisis sintctico para identificar los operadores y operandos de expresiones y proposiciones. Un componente importante del anlisis semntico es la verificacin de tipos, donde el compilador verifica que cada operador tenga operandos permitidos por la especificacin del lenguaje fuente. Sin embargo, la especificacin del lenguaje puede permitir ciertas conversiones.

    FIGURA 1.4: Fases de un compilador.

    4. Generacin de cdigo intermedio: algunos compiladores generan una representacin intermedia

    explcita del programa fuente. sta puede ser considerada como un programa para una mquina abstracta.

    5. Optimizacin de cdigo: esta etapa intenta mejorar el cdigo intermedio, de modo que resulte un cdigo de mquina ms rpido de ejecutar.

    6. Generacin de cdigo: corresponde a la fase final de un compilador y genera cdigo objeto, que habitualmente consiste en cdigo de mquina relocalizable o cdigo ensamblador. Aqu se seleccionan las posiciones de memoria para cada una de las variables empleadas por el programa. Un aspecto decisivo de esta etapa es la asignacin de variables a registros.

    7. Administrador de la tabla de smbolos: el registro de los identificadores utilizados en el programa fuente y la recoleccin de informacin relativa a los diferentes atributos de cada identificador conforman una de las funciones esenciales de un compilador. Dichos atributos pueden proporcionar informacin sobre la memoria asignada a un identificador, su tipo, su mbito y, en el caso de nombres de procedimientos, datos como el nmero y el tipo de sus argumentos, el mtodo con que se debe pasar cada argumento y, en caso de existir, el tipo que se retorna.

  • 13

    Compiladores

    Jacqueline Khler C. - USACH

    8. Tabla de smbolos: es una estructura de datos que contiene un registro por cada identificador, donde los campos son llenados con los atributos de este ltimo.

    9. Manejador de errores: cada una de las fases descritas puede encontrar errores. No obstante, cada fase debe tratar adecuadamente el error detectado para poder continuar la compilacin y as permitir la deteccin de ms errores en el programa fuente.

    1.6 CLASIFICACIN DE LOS COMPILADORES Existen diferentes criterios para clasificar los compiladores, segn la forma en que fueron construidos o la tarea que realizan: de una pasada, de mltiples pasadas, de depuracin, de optimizacin, etc. A pesar de stas diferencias, todos los compiladores llevan a cabo, en esencia, las mismas tareas bsicas. Ahora bien, existen algunos tipos de compiladores que pueden distinguirse de los dems: Ensamblador: compilador de estructura sencilla cuyo lenguaje fuente es el lenguaje ensamblador. Compilador cruzado: genera cdigo en lenguaje objeto para una mquina distinta de la que se est

    usando para compilar (por ejemplo, un compilador de pascal escrito en C++, que funcione en LINUX y que genere cdigo para MS-DOS). Es la nica forma de construir un compilador para un nuevo procesador.

    Compilador con montador: compila diferentes mdulos en forma independiente y despus es capaz de enlazarlos.

    Autocompilador: compilador escrito en el mismo lenguaje que va a compilar. No puede ser usado la primera vez, pero sirve entre otras cosas para hacer ampliaciones al lenguaje.

    Metacompilador: es un compilador de compiladores. Recibe como entrada las especificaciones del lenguaje para el que se desea construir un compilador y genera como salida el compilador para dicho lenguaje.

    Descompilador: recibe como entrada cdigo escrito en lenguaje de mquina y lo traduce a un lenguaje de alto nivel (no sirven en caso de existir optimizacin de cdigo en el programa escrito en lenguaje de mquina). En otras palabras, realiza el proceso inverso a la compilacin. No obstante, hasta ahora no se han construido buenos descompiladores (salvo desensambladores).

    1.7 HERRAMIENTAS TILES Existen diversas herramientas que pueden ser de ayuda al momento de construir un compilador. Dos de ellas, sin embargo, destacan por sobre las dems: Generadores de analizadores lxicos: generan analizadores lxicos en forma automtica, por lo

    general a partir de una especificacin basada en expresiones regulares. La organizacin bsica del analizador lxico resultante es en realidad un autmata finito. Ejemplo: Lex.

    Generadores de analizadores sintcticos: generan analizadores sintcticos, normalmente a partir de

    una entrada fundamentada en una gramtica independiente del contexto. Ejemplo: Yacc.

  • 14

    Compiladores

    Jacqueline Khler C. - USACH

    2 ANLISIS LXICO El anlisis lxico corresponde a la primera etapa del proceso de compilacin. Puede pensarse como una correccin ortogrfica del programa fuente. 2.1 FUNCIN DEL ANALIZADOR LXICO El analizador lxico es la primera etapa de un compilador y forma parte de la fase de anlisis. Su principal funcin consiste en leer los caracteres de entrada y elaborar como salida una secuencia de componentes lxicos que ser posteriormente utilizada para efectuar el anlisis sintctico. Generalmente el analizador lxico es una subrutina del analizador sintctico y su funcionamiento es el siguiente (ver figura 2.1): el analizador sintctico solicita el siguiente componente lxico. En consecuencia, el analizador lxico lee caracteres del programa fuente hasta identificar un nuevo componente lxico, que entregar al analizador sintctico para as dar cumplimiento a su solicitud. La figura 2.1 hace mencin de la tabla de smbolos, encargada de almacenar informacin relativa a cada uno de los nombres de variables y procedimientos declarados en el programa fuente. Ser estudiada con mayor profundidad en captulos posteriores.

    FIGURA 2.1: Interaccin entre el analizador lxico y el analizador sintctico.

    Como el analizador lxico es la parte del compilador que lee el texto fuente, tambin puede realizar ciertas funciones secundarias en la interfaz del usuario: Eliminar los comentarios del programa fuente. Eliminar espacios en blanco, tabulaciones y saltos de lnea. Relacionar los mensajes de error entregados por el compilador con el programa fuente. Por

    ejemplo, el analizador lxico suele contar los saltos de lnea detectados, por lo que puede asociar los errores encontrados al nmero de lnea del programa fuente correspondiente. Incluso existen compiladores en que el analizador lxico se encarga de hacer una copia del programa fuente donde se marcan los mensajes de error.

  • 15

    Compiladores

    Jacqueline Khler C. - USACH

    Se seal anteriormente que el analizador lxico suele ser una subrutina del analizador sintctico. Existen varias razones para separar estos dos tipos de anlisis en etapas diferentes: Quiz la ms importante de las consideraciones sea la de lograr un diseo sencillo. Separar el

    anlisis lxico del anlisis sintctico a menudo permite simplificar una u otra de estas etapas. Por ejemplo, un analizador sintctico que incluya las convenciones de espacios en blanco y comentarios resulta mucho ms complejo que otro que solo deba comprobar que stos ya hayan sido eliminados por el analizador lxico. En el caso de la creacin de un lenguaje nuevo, la separacin de las convenciones lxicas de las sintcticas puede traducirse en un diseo ms claro del lenguaje.

    Mejorar la eficiencia del compilador. Un analizador lxico independiente permite construir un procesador especializado y potencialmente ms eficiente para esta funcin. Gran parte del tiempo se consume en leer el programa fuente y dividirlo en componentes lxicos. Con tcnicas especializadas de manejo de buffers para la lectura de caracteres de entrada y procesamiento de componentes lxicos se puede mejorar significativamente el rendimiento de un compilador.

    Mejorar la portabilidad del compilador. Las peculiaridades del alfabeto de entrada y otras anomalas propias de los dispositivos pueden limitarse al analizador lxico. Por ejemplo, la representacin de smbolos especiales o no estndar (como en Pascal) puede ser aislada en esta etapa.

    2.2 COMPONENTES LXICOS, PATRONES Y LEXEMAS Un componente lxico (token) es una secuencia de caracteres que puede ser tratada como una unidad en la gramtica del lenguaje fuente. Un lenguaje clasifica los componentes lxicos en un conjunto finito de tipos. En la mayora de los lenguajes de programacin se consideran como componentes lxicos las siguientes construcciones: Palabras clave. Operadores. Identificadores. Constantes. Cadenas literales. Signos de puntuacin. La tabla 2.1 muestra ejemplos para algunos de los tipos de componentes lxicos tpicos de un lenguaje de programacin. Puede verse en estos ejemplos que en muchos casos existe un conjunto de cadenas (strings) para las cuales se produce un mismo componente lxico. Dicho conjunto de cadenas se describe mediante una regla llamada patrn, para cuya descripcin precisa se utiliza la notacin de expresiones regulares. Se dice que el patrn concuerda con cada cadena del conjunto. Una cadena de caracteres en el programa fuente con la que concuerde el patrn correspondiente a un componente lxico dado recibe el nombre de lexema. La tabla 2.2 muestra ejemplos de componentes lxicos, lexemas y patrones.

  • 16

    Compiladores

    Jacqueline Khler C. - USACH

    Tipo Ejemplo ID foo n14 sum

    NUM 73 0 00 515 082

    REAL 66.1 .5 10. 1e67 5.5e- 10

    IF If

    COMMA ,

    NOTEQ !=

    LPAREN (

    RPAREN )

    TABLA 2.1: Ejemplos de cadenas de caracteres y componentes lxicos asociados.

    En muchos lenguajes de programacin existen ciertas cadenas de caracteres que son reservadas, es decir, tienen un significado predefinido que no puede ser modificado por el usuario. Esto suele ser as para las palabras clave (for, char, break, etc.). Si las palabras clave no son reservadas, corresponde al analizador lxico la tarea de distinguir estas palabras de los identificadores, lo que puede resultar bastante complejo. Por ejemplo, en PL/1 es permitida la siguiente sentencia:

    IF THEN THEN THEN = ELSE; ELSE ELSE = THEN;

    Componente

    lxico Lexemas de ejemplo Descripcin informal del patrn

    const const const if if if relacin = < o = o > id pi, cuenta, D2 Letra seguida de letras y nmeros num 3.1416, 0, 6.02E23 Cualquier constante numrica literal vaciado de memoria Cualquier carcter entre y , excepto

    .

    TABLA 2.2: Componentes lxicos, lexemas y patrones. 2.3 ERRORES LXICOS Son pocos los errores que se pueden detectar directamente durante el anlisis lxico, puesto que el analizador lxico tiene una visin muy restringida del programa fuente. Por ejemplo, si en el programa fuente aparece:

    fi(a == f(x))

    El analizador lxico no puede distinguir si es un error de escritura de la palabra clave if o un identificador de funcin que no ha sido previamente declarado. De hecho, al ser un identificador vlido

  • 17

    Compiladores

    Jacqueline Khler C. - USACH

    debe retornar el componente lxico correspondiente. La deteccin de este error depender, en consecuencia, de otra fase del compilador. Si surge una situacin en la que el analizador lxico no puede continuar porque ninguno de los patrones concuerda con el prefijo de la entrada restante se pueden efectuar diferentes acciones de recuperacin de error: Borrar caracteres hasta encontrar algn componente lxico bien formado. Insertar caracteres faltantes. Reemplazar un carcter incorrecto por otro correcto. Intercambiar caracteres adyacentes. 2.4 IMPLEMENTACIN DE ANALIZADORES LXICOS 2.4.1 MTODOS GENERALES Existen tres mtodos generales para implementar un analizador lxico (lexer): Utilizar un generador de analizadores lxicos para crear el analizador lxico deseado a partir de una

    especificacin basada en expresiones regulares. En este caso, el generador proporciona rutinas para leer la entrada y manejarla con buffers.

    Escribir el analizador lxico en un lenguaje convencional de programacin de sistemas, utilizando las posibilidades de entrada y salida de este lenguaje para leer la entrada.

    Escribir el analizador lxico en lenguaje ensamblador y manejar explcitamente la lectura de la entrada.

    Las tres opciones han sido presentadas en orden de dificultad creciente para quien deba implementarlas. Lamentablemente, muchas veces los enfoques ms difciles de implementar dan como resultado analizadores lxicos ms rpidos. Independientemente del mtodo empleado, las herramientas tericas tiles para la construccin de analizadores lxicos son las expresiones regulares, para expresar los componentes lxicos en forma sencilla, y los autmatas finitos, para la implementacin de analizadores lxicos. 2.4.2 CONSTRUCCIN DE UN ANALIZADOR LXICO Muchos generadores de analizadores lxicos trabajan tomando como base las expresiones regulares correspondientes a los patrones de los diversos componentes lxicos de un lenguaje. Lo primero que debe hacerse es ordenar los diferentes patrones (representados como expresiones regulares) de acuerdo a su prioridad. Esto debe hacerse cuidadosamente, puesto que si el analizador lxico resultante detecta que un prefijo de la entrada se ajusta a dos o ms patrones diferentes, asignar a ese lexema el componente lxico de mayor prioridad. Una vez asignadas las prioridades, se construyen los AFND- para cada patrn (una buena idea es usar el mtodo de construccin de Thompson), donde el estado final de cada autmata tendr asociada una

  • 18

    Compiladores

    Jacqueline Khler C. - USACH

    accin. Esta accin corresponde a lo que debe hacerse al momento de detectar un lexema que concuerda con el patrn asociado al AFND-. A continuacin se unen los autmatas obtenidos para dar lugar a un nico AFND-. Para efectuar esta unin basta con crear un estado inicial con transiciones vacas hacia cada uno de los estados iniciales de los AFND- de cada patrn. Los estados finales conservan sus acciones asociadas. Cuando ya se ha construido el AFND- que reconoce todos los componentes lxicos del lenguaje, se debe proceder a convertirlo en un AFD mnimo. Al momento de minimizar se debe recordar que estados finales que tengan diferentes acciones asociadas no pueden ser equivalentes. El AFD mnimo obtenido corresponde al analizador lxico para el lenguaje especificado. Ejemplo 2.1:

    Construir el lxico mnimo que reconoce los patrones dados en la tabla 2.3 y les asigna el componente lxico correspondiente.

    TABLA 2.3: Patrones y componentes lxicos para el ejemplo 2.1. Se debe comenzar por ordenar jerrquicamente los patrones, segn su precedencia. Se asigna mayor precedencia a aquellos patrones que representen conjuntos ms pequeos de palabras. Esto es de vital importancia porque, en el caso de que dos patrones reconozcan un mismo lexema, deber ejecutarse la accin de mayor precedencia. En este caso, se tiene que el patrn solo coincide con el lexema a. Similarmente, el patrn solo coincide con el lexema abb . El patrn , en cambio, coincide con un conjunto ms amplio de lexemas: todos aquellos que tengan cero o ms a seguidas de una o ms b. En este caso, podemos observar que el lexema abb coincide con dos patrones: y . Como el patrn es ms limitado, debe tener una precedencia ms alta que . El patrn , en cambio, no tiene conflictos con los dems patrones, por lo que no importa qu lugar ocupe en la precedencia. A continuacin, necesitamos construir los AFND- reconocedores para los patrones dados, siguiendo el mtodo de Thompson (ver anexo A). Luego unimos estos tres AFND- con un nuevo estado inicial que tenga transiciones vacas hacia los estados iniciales de nuestros tres autmatas. El AFND- resultante se muestra en la figura 2.2. Es importante sealar que el reconocimiento de un lexema vlido va a estar dado por un estado final, y que cada estado final corresponde a un patrn diferente. As, a cada estado final se le asocia el componente lxico para el patrn correspondiente. Como reconoce lexemas que coincidan con el patrn , se le asocia el componente lxico . De manera similar, a se le asocia el componente lxico y a , el componente lxico .

  • 19

    Compiladores

    Jacqueline Khler C. - USACH

    = , , , , , con: = , , , , , , , , , , , , , , = , = = , ,

    FIGURA 2.2: AFND- para los patrones del ejemplo 2.1.

    Como no es posible implementar un AFND-, necesitamos encontrar un AFD equivalente (ver anexo A). No obstante, en la construccin de analizadores lxicos este proceso tiene una diferencia con respecto al mtodo formal que se utiliza en teora de autmatas. Segn esta ltima, en caso de no existir transiciones desde uno de los nuevos estados del AFD para algn smbolo, es decir, si la clausura es el conjunto vaco, se crea un nuevo estado para el AFD del que es imposible salir una vez que ha sido alcanzado. En la construccin de analizadores lxicos, sin embargo, resulta absurda la inclusin de este estado, puesto que impedira revisar el resto del programa fuente. En consecuencia, lo que se hace es construir un AFD que no tenga la transicin en cuestin (por ejemplo en la figura 2.3 se ve que no existe transicin desde el estado con el smbolo ). Si se alcanza un estado que no tiene transicin saliente con el prximo smbolo de la entrada, al implementar el analizador lxico se notifica un error lxico. La figura 2.3 muestra el AFD resultante. = , , , , , = , = , , , , = , , , , = , = = , , =

  • 20

    Compiladores

    Jacqueline Khler C. - USACH

    , = = , , = ! , = , , = , , , = " , = = , = = , , = !, = = ! !, = = ", = = ", = , , = , , , = $ , = = , = = $, = = $, = = Los estados finales del AFD tambin llevan asociada una accin. En caso de que uno de los estrados finales comprenda ms de una accin, se escoge aquella de mayor prioridad. Por ejemplo, el estado $ del AFD comprende los estados finales correspondientes a las acciones y , pero se le asocia solamente por tener una precedencia ms alta.

    FIGURA 2.3: AFD equivalente al AFND- de la figura 2.2.

    Es frecuente que el mtodo empleado para obtener el AFD equivalente entregue estados redundantes, por lo que se requiere minimizar el AFD obtenido. Si se considera el mtodo de las particiones para la minimizacin (ver anexo A), la teora de autmatas indica que la particin inicial viene dada por la separacin de estados finales y no finales. No obstante, en el caso de los analizadores lxicos los estados finales tienen asociadas diferentes acciones con diferentes prioridades, por lo que es necesario particionar tambin de acuerdo a la accin a

  • 21

    Compiladores

    Jacqueline Khler C. - USACH

    realizar. As, aquellos estados finales en que se ejecute una accin no sern equivalentes a los estados finales que ejecuten una accin diferente. La figura 2.4 muestra el AFD mnimo.

    % = &' ,

    '! (

    $)

    &' ,)" ,

    ' (

    '

    % = !

    )$

    '&* ,

    * (*

    "+

    % = %

    FIGURA 2.4: AFD mnimo equivalente al AFND- de la figura 2.2.

    2.5 EJERCICIOS 1. Dados los patrones de la tabla 2.4 y sus componentes lxicos asociados:

    a. Asigne las prioridades a considerar para construir el analizador lxico correspondiente. b. Indique, para cada uno de los siguientes lexemas, el componente lxico que debiera asociarle el

    analizador lxico. En caso de no corresponder con ninguno, seale la existencia de un error lxico. . . . . .

    TABLA 2.4: Patrones y componentes lxicos para el ejercicio 1.

  • 22

    Compiladores

    Jacqueline Khler C. - USACH

    2. Construya el analizador lxico mnimo para los siguientes patrones (El smbolo entre parntesis asociado a cada patrn corresponde al componente lxico asociado). + (). (). ().

    3. Construya el analizador lxico mnimo para los siguientes patrones (El smbolo entre parntesis

    asociado a cada patrn corresponde al componente lxico asociado). / + 0/ + 0 (). / + 0 (). // ().

  • 23

    Compiladores

    Jacqueline Khler C. - USACH

    3. ANLISIS SINTCTICO As como en la construccin de analizadores lxicos trabajamos con lenguajes regulares, los analizadores sintcticos se construyen sobre la base de una gramtica libre de contexto o GLC (ver anexo A). Aqu la gramtica corresponde a la especificacin del lenguaje de programacin, y se usan autmatas apiladores (ver anexo A) como reconocedores de programas sintcticamente correctos. 3.1 CONCEPTOS PREVIOS Antes de comenzar a construir analizadores sintcticos es necesario conocer algunos conceptos y algunas transformaciones que en ocasiones es necesario realizar sobre la gramtica. 3.1.1 RECURSIVIDAD POR LA IZQUIERDA Una gramtica es recursiva por la izquierda si tiene un no terminal tal que existe una derivacin 2 para alguna cadena 2. Para eliminar las recursiones directas, se agrupan las producciones del no terminal A de la siguiente manera: 2 | 2 | | 25 | 6 | 6 | | 67 Donde ninguna de las producciones 68 comienza por el no terminal . Luego se sustituyen las producciones de por: 6 | 6:| | 67: 2 | 2: | | 25:| Muchas veces no basta con eliminar las recursiones directas. Pueden existir recursiones por la izquierda que tarden ms en aparecer. Para eliminar este tipo de recursiones se puede usar el algoritmo que se muestra a continuacin, siempre que la gramtica no contenga ciclos (derivaciones de la forma ) ni producciones . Ntese, sin embargo, que la gramtica resultante s puede contener producciones : 1. Ordenar los no terminales en un cierto orden fijo (cualquiera) , , , 7. 2. Para (; = 1 hasta =):

    Para (> = 1 hasta ; 1): Si las producciones de ? son ? | | @, reemplazar cada produccin 8 ?A por

    8 A | | @A. Eliminar recursividad directa por la izquierda para 8.

    Ejemplo 3.1:

    Elimine toda recursin por la izquierda para $ = , N, %, C, donde: = , , , . N = C, D. P = C D | ,

    D DC | C. C = C.

  • 24

    Compiladores

    Jacqueline Khler C. - USACH

    Consideremos los no terminales en el orden C, D. Para cada no terminal, siguiendo el orden asignado a ellos, ejecutar los siguientes pasos: Paso 1 (no aplica para el primer smbolo): en cada produccin del no terminal actual que

    comience por un no terminal ya revisado , crear nuevas producciones para en que se reemplace con sus respectivas producciones.

    Paso 2: eliminar la recursin directa por la izquierda para el no terminal actual. C D | : como C es el primer no terminal, solo se debe eliminar la recursin directa. En este caso no existe recursin. D DC | C: en primer lugar, se busca cada produccin de D que comience con algn no terminal ya revisado (en este caso C) y se crean nuevas producciones para D en que C sea sustituido por sus producciones. As, se obtiene D DC | D | . D DC | D | : una vez realizado el primer paso, se debe eliminar la recursin directa por la izquierda, con lo que se obtiene D D | , C | . As, la gramtica sin recursin por la izquierda es $ = , N, %, C, donde: = , , , . N = C, D, . P = C D | ,

    D D | , C | .

    C = C. 3.1.2 FACTORIZACIN POR LA IZQUIERDA La factorizacin por la izquierda se ocupa de agrupar producciones semejantes, descomponindolas en un fragmento comn y otro diferente. Esto es de utilidad al momento de construir algunos analizadores sintcticos, pues sirve en aquellos casos en que no est claro cul de dos o ms producciones alternativas utilizar para ampliar un no terminal . As, las producciones de pueden reescribirse para postergar la decisin hasta haber visto lo suficiente de la entrada como para tomar la decisin correcta. Tmense por ejemplo las producciones A | . Como puede ser difcil saber si escoger o , se pueden crear las siguientes producciones para postergar la decisin: A B y B | . El algoritmo para factorizar completamente una gramtica es el siguiente: 1. Repetir:

    a. Para cada no terminal A, encontrar el prefijo ms largo comn a dos o ms de sus producciones.

    b. Si , sustituir todas las producciones de A, A | | | L | (donde representa a todas las producciones de A que no comienzan por ) por A B | y B | | | L, donde B es un nuevo no terminal.

    Mientras haya dos producciones para un no terminal con un prefijo comn.

  • 25

    Compiladores

    Jacqueline Khler C. - USACH

    Ejemplo 3.2: Factorice por la izquierda la gramtica $ = , N, P, S: = a, b N = A, B, C, D P = | ! | | ! | ,

    | ! | | ! | , | ! | | !,

    ! | ! | | ! | | | ! | !! | ! | !! | ! S = A. En el caso de , podemos comenzar por las producciones de la forma , de donde se obtiene: " | | ! | " | ! Ahora podemos factorizar aquellas producciones de la forma , quedando: | | ! " | Y terminar la factorizacin de este no terminal con las producciones de la forma , de donde se obtiene: | " " | ! Ntese que no se cre un no terminal nuevo porque ya exista uno con exactamente las mismas producciones. Para el no terminal , podemos comenzar con las producciones de la forma : $ | | ! | $ | ! Continuar con las de la forma : T | | ! T $ | Y terminar con las de la forma : T | $ Para el no terminal , podemos comenzar con las producciones de la forma : U | | ! U ! | Y terminar con las de la forma : U | U Para el no terminal !, podemos comenzar con las producciones de la forma ! :

  • 26

    Compiladores

    Jacqueline Khler C. - USACH

    ! U | ! | | ! | | | !! | ! | !! | ! Continuar con aquellas de la forma ! !: ! U | !U | | ! | | ! | !! | ! Seguir con aquellas de la forma ! : ! U | !U | | ! | U | ! | !! Seguir con aquellas de la forma ! : ! V | | ! | U | ! | !! V U | !U Y ahora tomar las de forma ! : ! W | | ! | ! | !! W V | U Para seguir con aquellas de forma ! : ! W | U | ! | !! Y luego las de forma ! !: ! W | U | !U Para terminar con aquellas de la forma ! : ! W | V As, la gramtica factorizada por la izquierda es $ = , N, P, S: = a, b N = A, B, C, D, E, F, G, H, I, J, K P = | " ,

    T | $, U | U,

    ! W | V, " | !, " | , $ | !, T $ | , U ! | , V U | !U, W V | U S = A.

  • 27

    Compiladores

    Jacqueline Khler C. - USACH

    3.1.3 CONJUNTOS ANULABLE, PRIMERO Y SIGUIENTE Existen dos funciones asociadas a una gramtica $ que facilitan la construccin de analizadores sintcticos: Primero y Siguiente. Ambas aportan informacin relativa al contexto de un smbolo dado. 3.1.3.1 Conjunto Anulable Antes de definir las dos funciones ya mencionadas es necesario introducir el conjunto anulable, _`, definido como el conjunto de todos aquellos no terminales que pueden, en uno o ms pasos, derivar a . Es decir, _` = _: . 3.1.3.2 Conjunto Primero Dada una cadena de smbolos gramaticales 2, se define su Conjunto Primero, %2,

    como el conjunto

    de terminales que pueden iniciar las secuencias derivadas a partir de 2. Sean ; , , , , 8, , 7 N y 2 N. Para calcular %c para todos los smbolos c (terminales y no terminales) de la gramtica, se deben aplicar las siguientes reglas: 1. % = . 2. %2 = . 3. Si se tienen las producciones | | | 7, entonces % = % % %7. 4. Si se tiene la produccin 7, entonces:

    % = %. Mientras 8 _`, % = % %8.

    3.1.3.3 Conjunto Siguiente Dado un no terminal , se define su Conjunto Siguiente, C, como el conjunto de terminales que pueden aparecer inmediatamente a la derecha de en alguna forma de frase, es decir, el conjunto de terminales tales que exista una derivacin de la forma C 26 para algn 2 y algn 6. Adicionalmente, si es posible que sea el smbolo situado ms a la derecha en alguna forma de frase, o sea, no puede venir nada ms a continuacin de , entonces $ C, donde $ indica el trmino de la secuencia (puede pensarse en $ de una manera similar al carcter especial de fin de archivo, "e). Sea C el smbolo inicial de la gramtica; sean 2, 6 cadenas de smbolos gramaticales (terminales y no terminales) y sean , _. El clculo de Ccc _requiere de la aplicacin de las siguientes reglas: 1. Agregar $ a CC. 2. Si se tiene la produccin 26, con 6 , entonces C = %6. 3. Si existe la produccin 2, entonces C = C. 4. Si se tiene la produccin 26, con 6 + , entonces C = %6 C.

  • 28

    Compiladores

    Jacqueline Khler C. - USACH

    Note que la regla 4 es una combinacin de las dos reglas anteriores. En ella, 6 podra no anularse, en cuyo caso debemos considerar la regla 2. Pero tambin puede darse que 6 se anule, en cuyo caso se cumple la regla 3. En consecuencia, debemos considerar todas las posibilidades. Ejemplo 3.3:

    Determine el Conjunto Anulable y los conjuntos %c y Cc, c _, para $ = , N, %, C, donde: = +,, , , /. N = , , , !, ". P = !,

    ", | /, ! +! | , " " | .

    C = . El conjunto anulable est conformado por todos aquellos terminales que, en una o ms derivaciones, pueden generar la secuencia vaca. As, el conjunto anulable para $ est dado por _` = !, ". _` pues todas sus producciones contienen terminales. _` pues su nica produccin comienza por , que tampoco lo es. Lo mismo ocurre para . % = %hi %/ = % / = / = , / % = %" = % = , / % = %! = % = , / %! = %+! % = %+ = + %" = % !" % = % = C = $ % = $ = $, C! = C C! = C = $, C = %! C %! C! = + $, $, = $, , + C" = C C" = C = $, , + C = %" C %" C" = $, , + $, , + = $, , +,

    3.2 DESCRIPCIN GENERAL DEL ANLISIS SINTCTICO Segn el diccionario de la Real Academia Espaola (2011), la sintaxis es la parte de la gramtica que ensea a coordinar y unir las palabras para formar las oraciones y expresar conceptos. En una segunda acepcin, define sintaxis como un conjunto de reglas que definen las secuencias correctas de los elementos de un lenguaje de programacin. Esta ltima definicin implica que todo lenguaje de programacin tiene reglas que prescriben la estructura de programas bien formados. Generalmente, un programa est formado por bloques. A su vez, los bloques estn conformados por proposiciones, las cuales se forman a partir de expresiones, y estas ltimas se forman con componentes lxicos:

    Programa bloques proposiciones expresiones componentes lxicos

  • 29

    Compiladores

    Jacqueline Khler C. - USACH

    Anteriormente vimos que el analizador lxico y el analizador sintctico trabajan en conjunto y que este ltimo obtiene como entrada una cadena de componentes lxicos entregada por el primero (ver figura 3.1). En este punto el analizador sintctico comprueba que la cadena pueda ser generada por la gramtica del lenguaje fuente. Tambin informa de cualquier error de sintaxis de manera inteligible, y debera recuperarse de los errores que ocurren frecuentemente para poder continuar procesando el resto de su entrada. Como resultado del anlisis sintctico se obtiene un rbol de derivacin que genera la secuencia de componentes lxicos a partir del smbolo inicial de la gramtica. Los analizadores sintcticos empleados generalmente en los compiladores se clasifican como descendentes o ascendentes. Como sus nombres indican, los analizadores sintcticos descendentes construyen el rbol desde arriba (la raz, dada por el smbolo inicial de la gramtica) hacia abajo (las hojas, consistentes en los componentes lxicos), mientras que los analizadores sintcticos ascendentes comienzan en las hojas y suben hacia la raz. En ambos casos, se examina la entrada al analizador sintctico de izquierda a derecha, un smbolo a la vez. Los mtodos descendentes y ascendentes ms eficientes trabajan slo con subclases de las gramticas libres de contexto, pero varias de estas subclases, como las gramticas LL y LR, son lo suficientemente expresivas para describir la mayora de las construcciones sintcticas de los lenguajes de programacin. Los analizadores sintcticos implementados a mano a menudo trabajan con gramticas LL(1). Los analizadores sintcticos para la clase ms grande de gramticas LR se construyen normalmente con herramientas automatizadas.

    FIGURA 3.1: Posicin del analizador sintctico en el modelo de un compilador.

    Como ya se seal, la salida del analizador sintctico es una representacin del rbol de anlisis sintctico para la cadena de componentes lxicos producida por el analizador lxico. En la prctica, no obstante, hay varias tareas que se pueden realizar durante el anlisis sintctico, como recoger informacin sobre distintos componentes lxicos en una tabla de smbolos, realizar la verificacin de tipo y otras clases de anlisis semntico, y generar cdigo intermedio. No obstante, estas actividades se vern ms adelante. 3.3 ALGUNOS ASPECTOS DEL MANEJO DE ERRORES SINTCTICOS Si un compilador tuviera que procesar slo programas correctos, su diseo e implementacin se simplificaran mucho. Pero los programadores a menudo escriben programas incorrectos y un buen

  • 30

    Compiladores

    Jacqueline Khler C. - USACH

    compilador debera ayudar al programador a identificar y localizar errores. Estos errores pueden ser de diversos tipos, por ejemplo: Lxicos, como escribir mal un identificador, palabra clave u operador. Sintcticos, como una expresin aritmtica con parntesis no equilibrados. Semnticos, como un operador aplicado a un operando incompatible. Lgicos, como una llamada infinitamente recursiva. A menudo, gran parte de la deteccin y recuperacin de errores en un compilador se centra en la fase de anlisis sintctico. Una razn es que muchos errores son de naturaleza sintctica o se manifiestan cuando la cadena de componentes lxicos que proviene del analizador lxico desobedece las reglas gramaticales que definen al lenguaje de programacin. El manejador de errores en un analizador sintctico tiene objetivos fciles de establecer: Informar de la presencia de errores con claridad y exactitud. Recuperarse de cada error con la suficiente rapidez como para detectar errores posteriores. No retrasar de manera significativa el procesamiento de programas correctos. Existen diferentes estrategias generales que puede emplear un analizador sintctico para recuperarse de un error: Recuperacin en modo de pnico: al descubrir un error, el analizador sintctico desecha smbolos

    de entrada, de uno en uno, hasta que encuentra uno perteneciente a un conjunto designado de componentes lxicos de sincronizacin. Estos componentes lxicos de sincronizacin suelen ser elementos de los conjuntos Primero y Siguiente, como por ejemplo los delimitadores (punto y coma, parntesis derecho) o el indicador de trmino de la entrada ($).

    Recuperacin a nivel de frase: al descubrir un error, el analizador sintctico puede realizar una correccin local de la entrada restante; es decir, puede sustituir un prefijo de sta por alguna cadena que permita continuar al analizador sintctico (suprimir un punto y coma sobrante, reemplazar una coma por un punto y coma, etc.).

    Producciones de error: si se tiene una buena idea de los errores comunes que pueden encontrarse, se puede aumentar la gramtica del lenguaje con producciones que generen las construcciones errneas. Entonces se usa esta gramtica aumentada con las producciones de error para construir el analizador sintctico. Si el analizador sintctico usa una produccin de error, se pueden generar diagnsticos de error apropiados para indicar la construccin errnea reconocida en la entrada.

    Correccin global: idealmente, sera deseable que un compilador hiciera el mnimo de cambios posibles al procesar una cadena de entrada incorrecta. Existen algoritmos para elegir una secuencia mnima de cambios para obtener una correccin global de menor costo. Por desgracia, la implementacin de estos mtodos es, en general, demasiado costosa en trminos de tiempo y espacio, as que estas tcnicas en la actualidad slo son de inters terico.

    3.4 ANLISIS SINTCTICO PREDICTIVO 3.4.1 ASPECTOS GENERALES El anlisis sintctico descendente puede verse como un intento de encontrar, usando las producciones de una gramtica dada y comenzando por el smbolo inicial, una derivacin por la izquierda para una cadena dada. Se estudiar en forma particular el anlisis sintctico predictivo (tambin denominado

  • 31

    Compiladores

    Jacqueline Khler C. - USACH

    anlisis sintctico LL(1) o anlisis sintctico por descenso recursivo), que es el ms utilizado gracias a su eficiencia. En el anlisis sintctico descendente se ejecuta un conjunto de procedimientos recursivos para procesar la entrada. En el caso particular del anlisis sintctico predictivo, el smbolo de la entrada determina sin ambigedad el procedimiento seleccionado para cada no terminal. En otras palabras, para construir un analizador sintctico de este tipo es necesario conocer, dada la entrada y el no terminal a expandir, cul de todas las posibles producciones de 2 | 2 | | 27 es la nica alternativa que genera una cadena que comience por . Es decir, debe ser posible detectar la alternativa apropiada con solo ver el primer smbolo que genera. De lo anterior se desprende que no cualquier gramtica libre de contexto es apropiada para el anlisis sintctico predictivo, sino que se requieren gramticas que no contengan recursiones por la izquierda y que estn factorizadas tambin por la izquierda. 3.4.2 CONSTRUCCIN Y FUNCIONAMIENTO DE ANALIZADORES SINTCTICOS LL(1) Se seal anteriormente que los analizadores sintcticos descendentes construyen el rbol de anlisis sintctico comenzando desde la raz, es decir, desde el smbolo inicial de $. Para este fin se sirve de una tabla de anlisis sintctico que indica qu produccin debe emplearse al momento de reemplazar un no terminal. Para la construccin de dicha tabla se emplea el algoritmo siguiente: 1. Para cada produccin 2, 2 , hacer:

    a. Para cada terminal en %2, aadir la produccin 2 en jk, l. b. Si _`, para cada terminal en C, aadir la produccin en jk, l.

    3. Hacer que cada entrada no definida de la tabla corresponda a un error. Si en alguna entrada de la tabla queda ms de una produccin, entonces se dice que no es posible construir un analizador sintctico LL(1). Cabe destacar que el analizador sintctico as construido es un autmata apilador. Inicialmente, la pila contiene al smbolo inicial de la gramtica al tope, seguido del delimitador de la entrada. Cada vez que se tenga un no terminal al tope de la pila y un terminal al comienzo de la entrada, el no terminal de la pila es reemplazado por el lado derecho de la produccin contenida en jk, l. Adicionalmente, es necesario considerar transiciones que permitan eliminar un smbolo terminal de la pila si ste coincide con el de la entrada. La aceptacin solo ocurre si tanto la pila como la entrada quedan vacas (solo con el delimitador de la entrada). Ejemplo 3.4:

    Construya la tabla de anlisis sintctico predictivo para $ = , N, %, C, donde: = +,, , , /. N = , , , !, ". P = !,

    ", | /, ! +! | ,

  • 32

    Compiladores

    Jacqueline Khler C. - USACH

    " " | . C = . Muestre la traza y el rbol sintctico para las entradas m = / + / / y m = / /. Sabemos que: _` = !, ". % = % = % = , / %! = + %" = C = C! = $, C = C" = $, , + C = $, , +, En primer lugar, para cada produccin 2 no vaca, debemos aadir dicha produccin en la posicin jk, l de la tabla para cada terminal %2:

    TABLA 3.1: Incorporacin de las producciones no vacas al analizador sintctico LL(1). A continuacin, en aquellos casos en que _`, para cada terminal C, aadir la produccin en jk, l. Ntese que en este paso no solo se agregan las producciones vacas presentes explcitamente en la gramtica, sino tambin aquellas que se pueden obtener en varios pasos. Una vez incorporadas estas producciones, el analizador sintctico predictivo ya est terminado. El resultado se muestra en la tabla 3.2.

    TABLA 3.2: Analizador sintctico LL(1) completo. Las figuras 3.2 y 3.3 muestran la traza para las dos entradas solicitadas con sus respectivos rboles sintcticos.

  • 33

    Compiladores

    Jacqueline Khler C. - USACH

    FIGURA 3.2: Traza y rbol sintctico resultante para la entrada m = / + / /.

    FIGURA 3.3: Traza y rbol sintctico resultante para la entrada m = / /.

  • 34

    Compiladores

    Jacqueline Khler C. - USACH

    Ejemplo 3.5: Construya la tabla de anlisis sintctico LL(1) para $ = , N, %, C, donde: n = k, l, , +,, , #, /. N = , , , !. % = kl | , ! | , ! | , ! #! | < > | / C = . $ No requiere eliminacin de recursin ni factorizacin, Por lo que podemos trabajar con ella tal como est. Comenzamos por determinar los conjuntos Anulable, Primero y Siguiente:

    _` = , , % = %kl % = k % % % = k #,

  • 35

    Compiladores

    Jacqueline Khler C. - USACH

    TABLA 3.4: Analizador sintctico LL(1) completo.

    3.4.3 GRAMTICAS LL(1) El algoritmo de construccin para analizadores sintcticos LL(1) puede ser aplicado a cualquier gramtica $. No obstante, si $ es ambigua o recursiva por la izquierda se tendr al menos una entrada de la tabla con ms de una definicin. Como para el anlisis sintctico predictivo se requiere poder determinar sin ambigedad qu produccin utilizar, ser necesario utilizar un subconjunto de las gramticas libres de contexto: las gramticas LL(1). La primera L del nombre hace referencia a que el anlisis se efecta de izquierda a derecha. La segunda, a que se deriva por a izquierda. El 1 indica que se examina un nico smbolo de la entrada antes de decidir qu produccin ocupar. Se dice que una gramtica es LL(1) cuando no es ambigua ni recursiva por la izquierda. Se puede demostrar que una gramtica es de este tipo si y solo si, cuando 2 | 6 sean dos producciones diferentes de $, se cumplen las siguientes condiciones: Para ningn terminal , tanto 2 como 6 derivan a la vez cadenas que comiencen por . A lo sumo una de las producciones 2 o 6 pueden derivar la cadena vaca. Si 6 , 2 no genera ninguna cadena que comience con un terminal en C. 3.4.4 RECUPERACIN DE ERRORES EN ANLISIS SINTCTICO LL(1) La pila de un analizador sintctico no recursivo hace explcitos los terminales y no terminales que el analizador espera emparejar con el resto de la tabla. En consecuencia, durante las siguientes explicaciones se har referencia a los smbolos de la pila. La deteccin de un error se produce cuando el terminal al tope de la pila no concuerda con el siguiente smbolo de la entrada o bien cuando en el tope de la pila se encuentra el no terminal , el siguiente smbolo de la entrada es y la entrada jk, l de la tabla no se encuentra definida. 3.4.4.1 Recuperacin de errores en modo de pnico Como se explic con anterioridad, este tipo de recuperacin de error consiste en eliminar smbolos de la entrada hasta encontrar algn componente lxico que pertenezca a un conjunto de componentes lxicos de sincronizacin. No obstante, se debe tener cuidado al elegir estos componentes de sincronizacin. Algunas tcnicas que se podran emplear son:

  • 36

    Compiladores

    Jacqueline Khler C. - USACH

    Colocar dentro del conjunto de sincronizacin para el no terminal todos los smbolos contenidos en C. Probablemente el anlisis sintctico podr continuar si se eliminan componentes de la entrada hasta encontrar algn elemento de C y se elimina el no terminal de la pila.

    En ocasiones puede ser necesario un conjunto de elementos de sincronizacin ms grande. Por ejemplo, podra ser til aadir al conjunto de sincronizacin de una construccin de menor jerarqua aquellos componentes que inician las construcciones de una jerarqua mayor.

    Pueden aadirse al conjunto de sincronizacin aquellos smbolos terminales contenidos en %. Si un no terminal puede generar , puede usarse esta produccin por omisin. Si no se puede descartar un terminal de la pila, puede eliminarse dicho terminal. Ejemplo 3.6:

    Considere el analizador sintctico LL(1) del ejemplo 3.4. Muestre la traza para la entrada m =/ / usando recuperacin de errores en modo de pnico. Usaremos Cc como conjunto de sincronizacin para cada no terminal: C = C! = $, C = C" = $, , + C = $, , +,

    TABLA 3.5: Traza con recuperacin de errores en modo de pnico para la entrada m = / / usando el analizador sintctico de la tabla 3.2.

    3.4.4.2 Recuperacin de errores a nivel de frase Consiste en llenar las entradas en blanco (entradas de error) de la tabla de anlisis sintctico con punteros a funciones de error. Estas funciones podran cambiar, insertar o eliminar smbolos de la entrada y enviar los mensajes de error apropiados. No obstante, no ser tratada a fondo en este curso.

  • 37

    Compiladores

    Jacqueline Khler C. - USACH

    3.5 ANLISIS SINTCTICO DESCENDENTE (POR DESPLAZAMI ENTO Y REDUCCIN) 3.5.1 ASPECTOS GENERALES Este tipo de anlisis sintctico intenta construir un rbol de anlisis sintctico para una secuencia de componentes lxicos comenzando desde las hojas y avanzando hacia la raz. En otras palabras, se reduce la secuencia de componentes lxicos de la entrada hasta tener solamente el smbolo inicial de la gramtica. En cada paso de reduccin se sustituye una subcadena de la entrada que concuerde con el lado derecho de una produccin por el no terminal del lado izquierdo de la misma (en otras palabras, si se tiene la produccin 2, la reduccin reemplaza la secuencia 2 por el no terminal ). Si en cada paso se escoge correctamente la subcadena a reemplazar, el resultado final es la traza de una derivacin por la derecha en sentido inverso. Ejemplo 3.7:

    Sea $ = , N, %, C, donde: n = , , ), ', *. N = C, , . % = C *, ) | , ' C = C. La cadena m = )'* puede reducirse en los siguientes pasos: )'* ( ) )'* ( )) '* ( ') * (C *) C Estas reducciones trazan, en sentido inverso, la derivacin: C * '* )'* )'*.

    Una manera de implementar el anlisis sintctico por desplazamiento y reduccin es mediante un AFD con una pila asociada. Inicialmente, la pila solo contiene el estado inicial del AA, mientras que la cadena m a analizar se encuentra en la entrada seguida del delimitador (es decir, m$). El analizador sintctico desplaza cero o ms smbolos de la entrada a la pila hasta que se reconozca el lado derecho 2 de una produccin 2 y entonces se reduce 2 reemplazndolo por el lado izquierdo de la produccin correspondiente (el no terminal ). Se repite este proceso hasta encontrar un error o hasta que la pila solo contenga al smbolo inicial de la gramtica y la entrada est vaca. Aunque las principales operaciones de este tipo de analizador sintctico son el desplazamiento y la reduccin, existen en realidad cuatro acciones diferentes: Desplazar: se desplaza el siguiente smbolo de la entrada al tope de la pila, seguido del nuevo

    estado del AFD. Reducir: se sustituye el lado derecho de una produccin, contenido en la pila, por su lado izquierdo.

  • 38

    Compiladores

    Jacqueline Khler C. - USACH

    Aceptar: anuncia el trmino exitoso del anlisis sintctico. Error: llama a una rutina de recuperacin de error. Ahora bien, existen algunas GLC en que un analizador sintctico por desplazamiento y reduccin puede alcanzar una configuracin donde, conociendo el contenido de la pila y el siguiente smbolo de la entrada, sea imposible decidir si efectuar un desplazamiento o una reduccin (conflicto desplazamiento/reduccin), o bien qu reduccin efectuar (conflicto reduccin/reduccin). Para evitar este tipo de problemas se utilizar un subconjunto de las gramticas independientes del contexto: la clase de gramticas LR(k). En consecuencia, el anlisis sintctico ascendente suele recibir el nombre de anlisis sintctico LR, por left-to-right parse, rightmost derivation. Lee la entrada de izquierda a derecha y construye una derivacin por la derecha en orden inverso. Adicionalmente, la k entre parntesis corresponde al nmero de smbolos de la entrada que son considerados al momento de decidir qu accin ejecutar. Cabe sealar que en la prctica no se usa r > 1 para la compilacin, pues se requieren tablas demasiado grandes. La familia de mtodos LR permite analizar un superconjunto de la clase de gramticas LL(1), es decir, DD1 Dt. Es posible construir analizadores sintcticos LR para reconocer prcticamente todas las construcciones de los lenguajes de programacin definidos mediante GLC, por lo que este esquema es el ms utilizado. 3.5.2 GRAMTICAS LR(K) Anteriormente se seal que existen casos en que un analizador sintctico por desplazamiento y reduccin tiene problemas para decidir qu accin ejecutar. Para que opere correctamente, este tipo de analizador sintctico debe ser capaz de decidir si reemplazar o reducir conociendo solamente los smbolos de la pila y los siguientes k elementos de la entrada. Sean dos producciones de cuyos lados derechos sean 26m | 260, respectivamente. Se puede observar que dichas producciones comparten el prefijo 26. Supngase adems que los primeros r smbolos de ambas producciones son los mismos. Como ambas producciones son iguales tanto en la pila como en la porcin de la cadena visible para el analizador, entonces la gramtica ser LR(k) si y solo si 26m = 260. 3.5.3 ANLISIS SINTCTICO SLR El primer mtodo de la familia LR que estudiaremos recibe su nombre por Simple Left-to-Right parser. No obstante, antes de construir un analizador sintctico de esta clase es necesario definir algunos conceptos. 3.5.3.1 Elemento LR(0) Un elemento LR(0) es una produccin de la gramtica $ con un punto en algn lugar del lado derecho. Por ejemplo, la produccin cuv produce cuatro elementos LR(0):

  • 39

    Compiladores

    Jacqueline Khler C. - USACH

    cuv c uv cu v cuv Es importante sealar que una produccin producir solamente el elemento . Intuitivamente, un elemento LR(0) indica hasta dnde se ha ledo una produccin en un momento dado del proceso de anlisis sintctico. El primer elemento del ejemplo anterior indica que se espera ver en la entrada una cadena derivable a partir de cuv. El segundo elemento indica que se ha ledo una cadena derivable a partir de c y que a continuacin se espera leer otra derivable de uv, etc. 3.5.3.2 Operacin Clausura Si es un conjunto de elementos LR(0) para una gramtica $, entonces la xyzy{ es el conjunto de elementos LR(0) construido a partir de segn las siguientes reglas: 1. Inicialmente, hacer xyzy{ = . 2. Si 2 6 xyzy{ y A es una produccin, hacer xyzy{ =

    xyzy{ A. Aplicar esta regla hasta que no sea posible aadir ms elementos a xyzy{.

    Ejemplo 3.8:

    Sea $ = , N, %, C, donde: n = +,, , , /. N = , , , !. % = , + | , ! | !, ! | / C = . Sea adems = . Determine xyzy{.

    Por regla 1: xyzy{ =

    Por regla 2, se deben agregar las producciones de : xyzy{ = , + ,

    Por regla 2, se deben aadir tambin las producciones de : xyzy{ = , + , , !, !

    Por regla 2, se deben aadir ahora las producciones de !: xyzy{ = , + , , !, !, ! , ! /

  • 40

    Compiladores

    Jacqueline Khler C. - USACH

    3.5.3.3 Construccin del autmata La idea central del mtodo SLR es construir, a partir de $, un AFD (considerando la definicin no estricta, en que cada estado tiene a lo ms una transicin por cada smbolo del alfabeto) con una pila asociada que permita reconocer los prefijos viables (es decir, que se pueden derivar a partir de alguna produccin). Para este fin se agrupan los elementos LR(0) en conjuntos que conforman los estados del AFD. Adems, el alfabeto del AFD est dado por todos los terminales y no terminales de la gramtica. El primer paso necesario para la construccin del AFD es aumentar la gramtica $ con una nueva produccin C C, donde C es un nuevo smbolo inicial, a fin de asegurar que el smbolo inicial tenga una nica produccin. Esta modificacin tiene por objeto indicar en qu momento se debe detener el anlisis sintctico y aceptar la cadena: es decir, cuando se est a punto de hacer la reduccin de C C. Ntese que esta nueva produccin no pasa a formar parte de la gramtica, sino que se usa exclusivamente para la construccin del estado inicial del AFD. El estado inicial del AFD est dado por = xyzy{ = C C. A continuacin se determinan las transiciones con todos aquellos smbolos precedidos por un punto en algn elemento LR(0) de . Para los nuevos estados, se determina la xyzy{ de los elementos LR(0) que le dan origen, es decir, aquellos del estado anterior con el punto desplazado en una posicin hacia la derecha. Las transiciones se determinan igual que para . Si nos encontramos ante un grupo idntico de elementos LR(0) que avanzan con un mismo smbolo que en algn estado anterior, dicha transicin avanza al estado ya conocido. Ejemplo 3.9:

    Sea $ = , N, %, C, donde: n = ,, , , , , + N = , , , ! % = | , | , | | | + C = Construya el AFD asociado al analizador sintctico SLR. Comenzamos por agregar la produccin C . El estado inicial del AFD queda dado por: = xyzy{ = C , es decir: = C

    +

  • 41

    Compiladores

    Jacqueline Khler C. - USACH

    Ahora debemos determinar las transiciones de . Como solo podemos tener a lo ms una transicin por cada smbolo del alfabeto, tenemos que: = C 1 1 2

    2 3 4 5 6 + + 7

    Ahora es necesario determinar los elementos LR(0) que conforman cada uno de los nuevos estados, as como las transiciones de estos ltimos: = xyzy{ = C , As, se tiene que: = C 8 = 9 = = 10

    4 5 6 + + 7

    = 11 11 2

    2 3 4 5 6 + + 7

    = = +

    = 12

    12 3 4 5 6 + + 7

    = 13

    4 5 6 + + 7

    = = 14 8 =

    9 = =

  • 42

    Compiladores

    Jacqueline Khler C. - USACH

    La tabla 3.6 muestra las transiciones del AFD obtenido.

    TABLA 3.6: Tabla de transiciones del AFD asociado al analizador sintctico SLR. 3.5.3.4 Construccin y operacin del analizador sintctico SLR Tomando como base la tabla de transiciones del AFD (tabla 3.6), se construye la tabla de anlisis sintctico SLR de la siguiente forma: 1. Incorporar la operacin de desplazamiento para cada transicin con un terminal. 2. Incorporar la aceptacin en el estado donde se tenga C C con $. 3. Para cada estado en que se tenga algn elemento LR(0) de la forma 2 , incorporar una reduccin por

    dicha produccin en ese estado para cada smbolo en C. 4. Toda casilla no definida de la tabla corresponde a un error. Ejemplo 3.10:

    Construya la tabla de anlisis sintctico SLR para la gramtica del ejemplo anterior. Muestre la traza y el rbol sintctico para m = + . Comenzamos por incorporar los desplazamientos y la aceptacin, como muestra la tabla 3.7. Antes de incorporar las reducciones, necesitamos conocer los conjuntos siguientes para cada no terminal. As, tenemos que:

    _` = % = % %hi % %+ = + = , , , + % = % % = % % = % = , , , + % = % % = % % = , , , +

  • 43

    Compiladores

    Jacqueline Khler C. - USACH