ANÁLISIS SINTÁCTICO. Comprobar que la secuencia de componentes léxicos cumple las reglas de la gramática Generar el árbol sintáctico

Documentos relacionados
Controla el flujo de tokens reconocidos por parte del analizador léxico. 4.2 Introduccion a las gramaticas libres de contexto y arboles de derivacion

ANÁLISIS SINTÁCTICO I ANALIZADORES SINTÁCTICOS

Analizadores sintácticos LR(0) y SLR

Recuperación de Errores

Tema 5. Análisis sintáctico ascendente

Lenguajes y Compiladores Análisis Sintáctico Parte I. Teoría Lenguajes 1

Analizador Sintáctico Ascendente

Compiladores: Análisis Sintáctico. Pontificia Universidad Javeriana Cali Ingenieria de Sistemas y Computación Prof. Gloria Inés Alvarez V.

Conceptos básicos sobre gramáticas

UNIVERSIDAD NACIONAL DE EDUCACIÓN A DISTANCIA Escuela Técnica Superior de Ingeniería Informática Procesadores de Lenguajes. Tema 4

Tipos de análisis deterministas. Análisis descendente. Tipos de análisis deterministas. Análisis ascendente. Análisis descendente

UNIVERSIDAD NACIONAL DE EDUCACIÓN A DISTANCIA Escuela Técnica Superior de Ingeniería Informática Procesadores de Lenguajes.

PROCESADORES DE LENGUAJE EXAMEN FINAL 8-JUNIO-07

Universidad Nacional del Santa Facultad de Ingeniería E.A.P. de Ingeniería de Sistemas e Informática TEORIA DE COMPILADORES ANALISIS SINTACTICO

16 Análisis sintáctico I

Procesadores de Lenguajes. Análisis sintáctico. Analizadores descendentes

UNIVERSIDAD NACIONAL DE EDUCACIÓN A DISTANCIA Escuela Técnica Superior de Ingeniería Informática Procesadores de Lenguajes. Tema 3.

18 Análisis sintáctico III Compiladores - Profr. Edgardo Adrián Franco Martínez. Clasificación de métodos de análisis sintáctico Análisis descendente

Tema 4: Análisis sintáctico ascendente. Análisis sintáctico ascendente: un ejemplo

Compiladores. Análisis Sintáctico Ascendente. Adrian Ulises Mercado Martínez. Facultad de Ingeniería, UNAM. 5 de septiembre de 2013

Procesadores de lenguaje

ANÁLISIS SINTÁCTICO I ANÁLISIS SINTÁCTICO DESCENDENTE LL(1)

Proyecto Intermedio Algoritmo de Earley

Procesadores de lenguaje Tema Análisis sintáctico (Parte II)

Compiladores: Análisis Sintáctico. Pontificia Universidad Javeriana Cali Ingenieria de Sistemas y Computación Prof. Gloria Inés Alvarez V.

Agenda. Introducción Analizador léxico Analysis El problema de analizar sintácticamente Analizador sintáctico descendeterecursivo

Unidad 5 Análisis semántico

Software para la Enseñanza de las Fases de Análisis Léxico y Análisis Sintáctico en Procesadores de Lenguajes

Análisis sintáctico 1

Definición de la sintaxis (1) Definición de la sintaxis (2) Definición de la sintaxis (3)

AUTÓMATAS DE PILA Y LENGUAJES INDEPENDIENTES DEL CONTEXTO

Lenguajes y Compiladores Aspectos Formales (Parte 2) Compiladores

Procesadores de Lenguaje

YACC (Yet Another Compiler Compiler) LALR(1) Parser Generator

Tema 3. Análisis sintáctico descendente

Teoría de Autómatas y Lenguajes Formales Práctica 4

Capítulo 4: Algoritmos usados por el Generador de Analizadores Sintácticos

Tema 5. Análisis semántico

Procesadores de lenguaje

Procesadores de lenguaje Tema Análisis sintáctico (Parte I)

Procesadores de lenguaje Tema 3 Análisis sintáctico (Parte I)

ANÁLISIS SINTÁCTICO II SLR

Tema 4: Gramáticas independientes del contexto. Teoría de autómatas y lenguajes formales I

ANÁLISIS SINTÁCTICO II LR1

Compiladores: Parsing ascendente

Unidad I: Análisis semántico

Unidad II: Análisis semántico

22, 23 y 24 Análisis sintáctico V Compiladores - Profr. Edgardo Adrián Franco Martínez

Objetivos Que el estudiante logre conocer, comprender y manejar conceptos y técnicas vinculados con el Analizador Léxico, para lo cual debe:

Tema 1. Introducción

ÁRBOLES DE SINTAXIS. Los nodos no terminales (nodos interiores) están rotulados por los símbolos no terminales.

Unidad IV Análisis Sintáctico. M.C. Juan Carlos Olivares Rojas

Contenido. Capítulo 1. Teoría de conjuntos. 1. Capítulo 2. Lenguaje. 39. Capítulo 3. Lenguajes formales. 55

Analizador Léxico. Programación II Margarita Álvarez. Analizador Léxico - Funciones

GRAMATICAS LIBRES DEL CONTEXTO

Tema 5 (2 a parte): Traductores ascendentes. Algoritmo de análisis ascendente. Procesamiento de Lenguajes. E E op T E T T num

El análisis descendente LL(1) 6, 7 y 13 de abril de 2011

Diseño de Compiladores I. Estructura General de un Compilador

Pontificia Universidad Católica del Ecuador

Yacc/Bison. Índice. Construcción del programa objetivo Flujo de control de las funciones yylex() e yyparse()

Compiladores: Sesión 16. Análisis semántico, traducción dirigida por sintaxis

Compiladores: Análisis Sintáctico. Pontificia Universidad Javeriana Cali Ingenieria de Sistemas y Computación Prof. Gloria Inés Alvarez V.

TEMA 5 ANÁLISIS SINTÁCTICO DESCENDENTE

Introducción. Análisis Semántico. José M. Castaño. Teoría de Lenguajes 2011 Departamento de Computación FCEyN, UBA

UNIVERSIDAD NACIONAL DE EDUCACIÓN A DISTANCIA Escuela Técnica Superior de Ingeniería Informática Procesadores de Lenguajes. Tema 2.

Análisis semántico. Análisis semántico. Índice (I)

PROGRAMA DE LABORATORIO SECCIÓN: ÁREA A LA QUE PERTENECE: POS-REQUISITO: AUXILIAR:

GENERACIÓN DE CÓDIGO INTERMEDIO ÁRBOLES DE SINTAXIS ABSTRACTA (ASA)

Análisis Sintáctico Descendente

4 o Ingeniería Informática

Procesadores de Lenguaje

Sintaxis y Semántica del Lenguaje

Las Etapas de la Compilación

Lenguajes y Compiladores Aspectos Formales (Parte 1) Compiladores

Clase 16: GLC s recursivas y no factorizadas Solicitado: Ejercicios 13: Recursividad y factorización de gramáticas

Generación de Código Intermedio

Lex (flex,... ) Generación de analizador léxico p.1

Desarrollo del Programa Docente de Procesadores del Lenguaje

Tema: Análisis Sintáctico

Análisis léxico. Formalización y desarrollo. Procesadores de Lenguajes. Ingeniería Técnica superior de Ingeniería Informática

LEX. Las definiciones y subrutinas son opcionales. El segundo %% es opcional pero el primer %% indica el comienzo de las reglas.

Compiladores e Intérpretes Análisis Semántico I

UNIVERSIDAD NACIONAL AUTÓNOMA DE MÉXICO FACULTAD DE INGENIERÍA PROGRAMA DE ESTUDIO

Universidad de Valladolid

Compiladores e intérpretes Análisis Léxico I. Análisis Léxico I

Elementos para el estudio de los compiladores

Introducción. El proceso de traducción

Universidad de Costa Rica. Escuela de Ciencias de la Computación e Informática CI-2700 TÓPICOS ESPECIALES - COMPILADORES.

DESARROLLO DE LA PRÁCTICA DE ANÁLISIS SINTÁCTICO

Examen de Procesadores de Lenguaje

Tema 5: Traducción dirigida por la sintaxis

Introducción al Diseño de Compiladores. Año

Profesor: José Miguel Rubio L.

ANÁLISIS LÉXICO Ing. Ronald Rentería Ayquipa

LENGUAJES Y GRAMÁTICAS

El proceso del Análisis Léxico

Ciencias de la Computación I

Gramáticas de Atributos

Fundamentos de Ciencias de la Computación Trabajo Práctico N 2 Lenguajes Libres del Contexto y Sensibles al Contexto Segundo Cuatrimestre de 2002

Capítulo 3 Análisis sintáctico

Transcripción:

Cadena de tokens Árbol Sintáctico ANÁLISIS SINTÁCTICO 1 Análisis Sintáctico 2 Funciones Comprobar que la secuencia de componentes léxicos cumple las reglas de la gramática Generar el árbol sintáctico Ventajas de utilizar gramáticas Son especificaciones sintácticas y precisas de lenguajes Se puede generar automáticamente un analizador El proceso de construcción puede llevar a descubrir ambigüedades Imparte estructura al lenguaje de programación, siendo más fácil generar código y detectar errores Es más fácil ampliar y modificar el lenguaje 1

Analizador Sintáctico, Tipos 3 Tres tipos generales de analizadores sintácticos: Métodos Universales: Cocke-Younger-Kasami y Earley Sirven para cualquier gramática Muy ineficientes Descendentes (top-down) Construyen el árbol de análisis sintáctico desde arriba (raíz, axioma) hasta abajo (hojas, terminales) Analizadores Descendentes Recursivos Analizadores LL(1) con tabla Ascendentes (bottom-up) Construyen el árbol de análisis sintáctico desde abajo hacia arriba Analizadores de Precedencia de Operador Analizadores LR(1) Analizador Sintáctico 4 Tanto para el análisis descendente como para el ascendente: La entrada se examina de izquierda a derecha, un símbolo cada vez Trabajan con subclases de gramáticas En general las gramáticas serán LL y LR LR(k) LL(k) En la práctica solo se utilizan LR(1) y LL(1) Muchos compiladores se llaman parser-driven debido a que el analizador sintáctico es el que llama al léxico Existen herramientas para generar automáticamente analizadores sintácticos (YACC, Bison) 2

Análisis Sintáctico Descendente 5 Algoritmo 1. Poner el axioma como raíz del árbol de derivación 2. Hasta que solo haya símbolos terminales, derivar más a la izquierda Ejemplo Entrada: Id.*.Id.+.Id Gramática: Expresión::=Expresión.*.Término Expresión.+.Término Término Término ::= Id Número Derivación: Expresión Expresión.+.Término Expresión.*.Término.+.Término Término.*.Término.+.Término Id.*.Término.+.Término Id.*.Id.+.Término Id.*.Id.+.Id Análisis Sintáctico Ascendente 6 Definición: Pivote Secuencia más larga de símbolos ( T y N ) en la parte más izquierda de la entrada que se puede encontrar en la parte derecha de una producción y tal que todos los símbolos a su derecha son terminales Ejemplo: Si entrada es: Expresión.*.Término.+.Id el pivote es: Expresión.*.Término Algoritmo 1. Empezar con la cadena de entrada 2. Intentar llegar hasta el axioma, encontrando el pivote y reduciéndolo con la producción correspondiente Ejemplo Id.*.Id.+.Id Término.*.Id.+.Id Expresión.*.Id.+.Id Expresión.*.Término.+.Id Expresión.+.Id Expresión.+.Término Expresión 3

7 Analizadores Sintácticos, Problemas Descendentes Mas de una opción: A::= Retroceso Analizar los siguientes elementos de la entrada Recursividad izquierda Eliminación de la recursividad Ambigüedad Factorización por la izquierda Ascendentes Más de una opción: A::= y es el pivote Otros Problemas semánticos Análisis Sintáctico Predictivo 8 No necesita realizar retroceso para analizar bien las sentencias del lenguaje Sólo con ver el siguiente carácter de la entrada puede decidir cuál va a ser la siguiente producción a emplear Condiciones Diseñar bien la gramática Eliminar la recursividad izquierda Factorizar por la izquierda No está asegurado el tener una gramática predictiva Las gramáticas son difíciles de leer Para las partes de las gramáticas que no son predictivas se pueden utilizar otros analizadores 4

Análisis Sintáctico Predictivo 9 Árbol sintáctico Ejemplo: Id.*.Id.+.Id Expresión Expresión + Término Expresión * Término Id Término Id Id 10 Análisis Sintáctico Predictivo: Descendente Recursivo Se ejecuta un conjunto de procedimientos recursivos para procesar la entrada A cada NO Terminal de una gramática se le asocia un procedimiento Decide la producción que utilizará analizando el símbolo de preanálisis, si está en PRIMERO() entonces se usa la producción con lado derecho si no está en ningún PRIMERO entonces se usa una producción Usa una producción imitando al lado derecho no terminal da como resultado una llamada a otro procedimiento terminal (que coincide con el símbolo de preanálisis) produce otra lectura de otro token. Si el token no coincide entonces Error La secuencia de procedimientos llamados para procesar la entrada define implícitamente un árbol de análisis sintáctico 5

11 Análisis Sintáctico Predictivo: Descendente Recursivo Ejemplo: S if B then S write B i := B B i = i i <> i true false Procedure S; begin if car= i then begin scan; if car = asig then scan else error; B end elseif car= if then begin scan; B; if car= then scan else error; S; end elseif car=write then begin scan; B end else error end; Procedure B; begin if car= i then begin scan; if car in [igual, noigual] then scan else error; if car = i then scan else error; end elseif car = in [true, false] then scan else error end; 12 Análisis Sintáctico Predictivo, DEFINICIONES: PRIMERO Si es una cadena de símbolos gramaticales, PRIMERO() es el conjunto de terminales que inician las cadenas derivadas de. PRIMERO()={x ( * x.), (x T {}), ( * )} Conjunto PRIMERO(X) para todos los símbolos gramaticales X 1. Repetir hasta que no se puedan añadir más terminales o a ningún conjunto PRIMERO 2. Si X T PRIMERO(X) es { X } 3. Si X añadir a PRIMERO(X) 4. Si X N y X Y 1 Y 2...Y K Y a PRIMERO(X) si a PRIMERO(Y i ) y PRIMERO(Y 1 ), PRIMERO(Y 2 ),..., PRIMERO(Y i-1 ) Si Y 1 deriva a se añade PRIMERO(Y 2 ) Si Y 1 no deriva a no se añade más a PRIMERO(X) 6

13 Análisis Sintáctico Predictivo, DEFINICIONES: PRIMERO PRIMERO(), Ejemplo: E ::= T.E E ::= +.T.E T ::= F.T T ::= *.F.T F ::= (.E.) Id PRIMERO(E) = { (, Id } PRIMERO(T.*.Id) = { (, Id } PRIMERO(T) = { (, Id } PRIMERO(Id.+.Id) = { Id } PRIMERO(F) = { (, Id } PRIMERO(Id) = { Id } PRIMERO(E ) = { +, } PRIMERO(T ) = { *, } 14 Análisis Sintáctico Predictivo, DEFINICIONES: SIGUIENTE Conjunto SIGUIENTE(A) SIGUIENTE(A)={x (S * A ), (A N ), ( * ), ( + ), (xprimero()-{})} Conjunto de terminales que pueden aparecer inmediatamente a la derecha de A en alguna forma sentencial, si A es el último símbolo entonces se incluye el separador $ Algoritmo 1. SIGUIENTE(S)={$} 2. La regla AB SIGUIENTE(B) = (PRIMERO()-{}) SIGUIENTE(B) 3. La regla AB =, * ( PRIMERO()) SIGUIENTE(B) = SIGUIENTE(A) SIGUIENTE(B) 4. Repetir hasta que no cambie ningún conjunto SIGUIENTE 7

15 Análisis Sintáctico Predictivo, DEFINICIONES: SIGUIENTE SIGUIENTE(A), Ejemplo: E ::= T.E E ::= +.T.E T ::= F.T T ::= *.F.T F ::= (.E.) Id N SIGUIENTE E $, ) E $, ) F $, *, ), + T $, +, ) T $, +, ) 16 Análisis Sintáctico Predictivo: Condiciones Pregunta: Que debe cumplir una gramática para que pueda ser reconocida sin retroceso, con solo mirar el siguiente elemento de la entrada, de forma descendente? Respuesta: Si A::= PRIMERO() PRIMERO() =. para ningún terminal a tanto y derivan a la vez cadenas que comiencen con a No puede ocurrir que * y * Si *, entonces no deriva ninguna cadena que comience con un terminal en SIGUIENTE(A) Condición LL(1) 8

17 Análisis Sintáctico Predictivo: Condiciones Condición LL(1) No puede haber conflictos PRIMERO/PRIMERO N N, el conjunto PRIMERO de todas sus alternativas debe ser disjunto No puede haber múltiples alternativas nulas N N, solo pueden tener una producción N No puede haber conflictos PRIMERO/SIGUIENTE N N, con una alternativa nula, SIGUIENTE(N) debe ser disjunto de los conjuntos PRIMERO de todas sus alternativas No puede haber entradas con definiciones múltiples en la tabla de análisis 18 Análisis Sintáctico Predictivo: Tabla de Análisis Sintáctico Funcionamiento Sea A con a T aprimero(). El analizador sintáctico expandirá A por cuando el símbolo actual de la entrada sea a Algoritmo 1) ForAll (A::= ) do a) ForAll a PRIMERO() do TABLA[A,a]= b) Si PRIMERO() Entonces ForAll b SIGUIENTE(A) do TABLA[A,b]= c) Si PRIMERO() $ SIGUIENTE(A) Entonces do TABLA[A,$]= 2) ForAll A N y c T do a) If TABLA[A,c]= Then TABLA[A,c]= error 9

19 Análisis Sintáctico Predictivo: Tabla de Análisis Sintáctico Ejemplo E ::= T.E E ::= +.T.E T ::= F.T T ::= *.F.T F ::= (.E.) Id Id + * ( ) $ E T.E T.E E +.T.E T F.T F.T T *.F.T F Id (.E.) 20 Análisis Sintáctico Predictivo No Recursivo; LL(1) Modelo de analizador sintáctico predictivo no recursivo ENTRADA a + b $ PILA X Y Z $ Programa de Análisis Sintáctico Predictivo Tabla de Análisis Sintáctico M SALIDA 10

21 Análisis Sintáctico Predictivo No Recursivo; LL(1) Los símbolos de la entrada actual a y cima de la pila X determinan la acción del analizador Hay tres posibilidades: X=a=$, el analizador se detiene y anuncia el éxito del análisis X=a$, el analizador saca X de la pila y mueve el apuntador de la entrada al siguiente símbolo de entrada X N, el programa consulta la entrada M[X,a] Si M[X,a]=UVW, se sustituye la X de la pila por WVU (U queda como cima de la pila) Si M[X,a]= error, se llama a la rutina de recuperación de error Análisis Sintáctico LL(1) 22 Algoritmo: pila =$; meter$ al final de la entrada; a:= GetToken; Push S; Repeat If X T or X=$ then If X=a then Pop; a:= GetToken; Else error; Else If M[X,a]=XY 1 Y 2..Y k then Pop; Push Y k,y k-1,...,y 1 Emitir la producción X else error(); until X=$ If X=$ and a=$ then Aceptar; else error(); 11

Análisis Sintáctico LL(1) 23 Ejemplo: Pila Entrada Producción $ E Id * Id + Id $ E::= T E $ E T Id * Id + Id $ T::= F T $ E T F Id * Id + Id $ F::= Id $ E T Id Id * Id + Id $ $ E T * Id + Id $ T ::= * F T $ E T F * * Id + Id $ $ E T F Id + Id $ F::= Id $ E T Id Id + Id $ $ E T + Id $ T ::= $ E + Id $ E ::= + T E $ E T + + Id $ $ E T Id $ T::= F T $ E T F Id $ F::= Id $ E T Id Id $ $ E T $ T ::= $ E $ E ::= $ $ Análisis Sintáctico Ascendente 24 Análisis por desplazamiento y reducción Por precedencia de operadores LR Construir un árbol de análisis sintáctico para una cadena de entrada que comienza por las hojas y avanza hacia la raíz. Reducir una cadena de entrada w al símbolo inicial de la gramática En cada paso de reducción se sustituye una subcadena que concuerde con el lado derecho de una producción por el símbolo del lado izquierdo, se traza una derivación por la derecha en sentido inverso 12

25 Análisis Sintáctico Ascendente: Gramática de Operadores Para una pequeña clase de gramáticas se puede construir con facilidad, a mano, eficientes analizadores sintácticos por desplazamiento y reducción Gramática de operadores No tiene reglas de producción del tipo A::= No tiene dos no terminales adyacentes A::= B C A,B,C N Ejemplo No es G. de operadores Si es G. de operadores EEAE (E) -E id A+ - * / EE+E E-E E*E E/E (E) -E id 26 Análisis Sintáctico Ascendente: Precedencia de Operador Inconvenientes Es difícil de manejar componentes léxicos con dos precedencias distintas, como el signo menos (unario y binario) No se puede tener la seguridad de que el analizador acepta exactamente el lenguaje deseado Sólo una pequeña clase de gramáticas puede analizarse Ventajas Sencillez Se pueden establecer relaciones de precedencia (* precede a +) Se aplican con otros analizadores para la parte que no son de operador 13

27 Análisis Sintáctico Ascendente: Precedencia de Operador El análisis recorre la entrada de izquierda a derecha y se encuentra en dos posibles estados: Esperando un operador Esperando un operando El análisis mantiene dos pilas Pila de Operadores Pila de Operandos Cuando un operador en la cima de su pila es de más prioridad que el siguiente de la pila, entonces el pivote consiste en ese operador junto a los dos operandos situados más arriba de la pila de operandos 28 Análisis Sintáctico Ascendente: Precedencia de Operador Entrada: Id + Id * Id Gramática E:=E + E E * E ( E ) Id La gramática es ambigua pero este tipo de análisis proporciona una única derivación Entrada Pila de Operadores Pila de Operandos Id a + Id b * Id c + Id b * Id c Id a Id b * Id c + Id a * Id c + Id b Id a Id c *+ Id b Id a *+ Id c Id b Id a 14

29 Precedencia de Operador: Relaciones de Precedencia Se definen tres relaciones de precedencia disjuntas a< b si a tiene menos precedencia que b a=b si a tiene igual precedencia que b a >b si a tiene más precedencia que b Algoritmo Sustituir todos los símbolos no terminales por un único símbolo Insertar $ al principio y al final de la cadena de entrada Insertar las relaciones de precedencia en la cadena de entrada Mientras entrada$s$ hacer Recorrer entrada desde la izquierda hasta encontrar > Buscar a la izquierda, a partir de ese punto, el primer < Reducir el pivote que se encuentra en el medio Reinsertar las relaciones de precedencia, ignorando los no terminales 30 Precedencia de Operador: Ejemplo Entrada: $ ( Id + Id ) $ Gramática: E::= E + E E * E ( E ) Id Tabla de precedencia: ( Id * + ) $ ) > > > > Id > > > > * < < > > > > + < < < > > > ( < < < < = $ < < < < = Análisis Entrada Derivación $ < ( < Id > + < Id > ) >$ $ ( E + Id ) $ $ < ( < E + < Id > ) > $ $ ( E + E ) $ $ < ( < E + E > ) > $ $ ( E ) $ $ < ( E = ) > $ $ E $ 15

31 Obtención de las relaciones de precedencia x y sii existe: A::=...xBy... B{N } x < y sii existe: A::=...xB... C{N } B::=+Cy... x > y sii existe: A::=...By... C{N } B::=+...xC 32 Precedencia de Operador: Construir la Tabla de Precedencia Si el operador 1 tiene mayor precedencia que 2 entonces hacer 1 > 2 y 2 < 1 Si los operadores 1 y 2 son de igual precedencia (por ejemplo el mismo operador), entonces hacer: 1 > y 2 > 1 si son asociativos por la izquierda 1 < y 2 < 1 si son asociativos por la derecha Hacer < Id, Id >, < (, (<, ) >, >), >$, $< (=) $< ( $< Id (< ( Id >$ ) >$ (< Id Id >) ) >) 16

33 Precedencia de Operador: Construir la Tabla de Precedencia Definiciones: Cabecera(A) = { x (A * x ) (x T ) (A N ) ( N* ) ( * )} Último(A) = { x (A * x ) (x T ) (A N ) ( * ) ( N* )} Ejemplo: E::=E + E T T::=T * F F F::=( E ) Id Propiedad: Cabecera(E)={+, *, (, Id} Último(E)={+, *, ), Id} (A::= B a C ) P, a T, A, B, C N,, *, a siempre aparece en un nivel superior a los símbolos terminales de Cabecera(C) y Último(B) en el árbol de derivación 34 Precedencia de Operador: Construir la Tabla de Precedencia Reglas: (A::= B a C ) P, a T, A, B, C N,, * 1. c Cabecera(C), a < c 2. b Último(B), b > a 3. (A::= a b ) P, a, b T, a=b, * Si existe más de una relación de precedencia entre dos símbolos terminales, no es una gramática de precedencia Algoritmo ForAll (A::= B a C ) P do Calcular Cabecera(C) Calcular Último(B) Calcular las precedencias usando las reglas 1, 2 y 3 ForAll a Cabecera(S) do $ < a ForAll a Último(S) do a > $ 17

35 Precedencia de Operador: Construir la Tabla de Precedencia Gramática E::=E + E T T::=T * F F F::=( E ) Id Cabecera y Último Tabla N Cabecera Último E +, *, (, Id +, *, ), Id T *, (, Id *, ), Id F (, Id ), Id Regla Precedencias(R 2 ) Precedencias (R 1 ) E::=E+T +, *, ), Id > + + < *, (, Id E::=T+F *, ), Id > * * < (, Id 36 Precedencia de Operador: Operadores Unarios ( ) Manejo de Operadores Unarios ( ) Operador Unario que no es además Binario < > si tiene mayor precedencia que < si tiene menor precedencia que Operador Unario que además es Binario Mediante la tabla de precedencia no puede analizarse correctamente cadenas como: Id*-Id Solución: Utilizar el analizador léxico para devolver dos componentes léxicos distintos, recordando el componente léxico anterior debe distinguir uno de otro. Ejemplo: Es el menos unario si antes el componente léxico leído era un operador, un paréntesis izquierdo, una coma o un símbolo de asignación 18

37 Precedencia de Operador: Funciones de Precedencia La tabla de precedencia se puede simplificar, con el objetivo de ahorrar memoria y aumentar la velocidad de proceso, mediante dos funciones f y g Transforman los símbolos terminales en enteros Tienen que cumplir que a,b T si a < b, f(a) < g(b) si a = b, f(a) = g(b) si a > b, f(a) > g(b) Para encontrar la relación de precedencia entre a y b se realiza una comparación entre f(a) y g(b) No todas las relaciones de precedencia tienen funciones de precedencia 38 Precedencia de Operador: Funciones de Precedencia Construcción de las Funciones de Precedencia 1. Crear los símbolos f a y g a a T {$} 2. Se dividen los f a y g a en tantos grupos como sea posible: Si a=b entonces f a y g b están en el mismo grupo 3. Crear un grafo dirigido cuyos nodos son los grupos encontrados en el paso 2, los arcos se etiquetan: si a< b, g b f a si a >b, f a g b 4. Ciclos en el grafo: Respuesta SI, entonces no existen funciones de precedencia Respuesta NO, entonces f(a) y g(a) son los caminos más largos que comienzan en f a y g a 19

39 Precedencia de Operador: Funciones de Precedencia Ejemplo Id + * $ Id > > > + < > < > * < > > > $ < < < Cada símbolo está solo en un grupo g Id g * g + g $ f Id f * f + f $ 40 Precedencia de Operador: Funciones de Precedencia No hay ciclos, entonces existen las funciones de precedencia. Como las funciones de $ no tienen arcos entonces f($)=g($)=0 El camino más largo desde g + tiene longitud 1, entonces g(+)=1 El camino más largo desde g Id a f * a g * a f + a f $ por tanto g(id)=5 Id + * $ f 4 2 4 0 g 5 1 3 0 20

Análisis Ascendente LR 41 LR(k): Left-to-right, rightmost derivation, ( *, * T) k símbolos de entrada son necesarios para tomar las decisiones de análisis sintáctico Ventajas Es el método de análisis por desplazamiento y reducción sin retroceso más general, a pesar de esto es igual de eficiente La clase de gramáticas que pueden analizarse es un supraconjunto de la clase de gramáticas que pueden analizarse con analizadores sintácticos predictivos Detectan los errores sintácticos tan pronto como es posible en un examen de izquierda a derecha de la entrada Se pueden reconocer prácticamente todas las construcciones de los lenguajes de programación descritos por una gramática G2 Inconvenientes La construcción a mano requiere mucho trabajo Tipos de Análizadores LR 42 LR simple (SLR) Fácil de implementar Menos poderoso, hay algunas gramáticas que los otros métodos pueden analizar y este no puede LR canónico Es muy costoso de implementar El más potente LALR (LR con examen por anticipado) Intermedio entre los dos métodos anteriores 21

Modelo de un Analizador LR 43 ENTRADA a 1... a 1... a n $ Pila s m X m Programa de Análisis Sintáctico LR SALIDA s m-1 X m-1... s 0 Acción Ir_a Tabla de Análisis Sintáctico LR Modelo de Analizador LR 44 El programa es el mismo para todos los analizadores LR X i es un símbolo gramatical y cada s i es un símbolo llamado estado Se utiliza el símbolo de estado y el símbolo de la entrada para indexar la tabla y determinar la acción siguiente La tabla de análisis sintácticos tiene dos partes: Acción[s m, a i ]= Error: error de sintaxis Aceptar: acepta la entrada, el análisis sintáctico finaliza Desplazar: introduce en la pila el símbolo a i y el estado s m Reducción: extrae símbolos de la pila, ejecuta la acción semántica correspondiente a una producción Ir_a[s m, X i ]= s k 22

Modelo de Analizador LR 45 Configuración de un analizador sintáctico LR Tupla con el contenido de la pila y la entrada que resta por procesar (s 0 X 1 s 1 X 2 s 2... X m s m, a i a i+1... a n $) Acción[s m, a i ] = desplazar s (s 0 X 1 s 1 X 2 s 2... X m s m a i s, a i+1... a n $) Acción[s m, a i ] = reducir A (s 0 X 1 s 1 X 2 s 2... X m-r s m-r A s, a i a i+1... a n $) donde s=ir_a[s m-r, A] y r= (se extraen r símbolos no terminales y r símbolos de estados de la pila) Algoritmo de Análisis LR 46 apuntar ae al primer símbolo de w$ (s está en la cima y ae apunta al símbolo a) repetir caso Acción[s, a] Desplazar s push a push s leer en la entrada Reducir A pop 2* símbolos s símbolo en la cima de la pila s= Ir_a[s, A] push A push s Aceptar Error fincaso hasta Aceptar o Error 23

Ejemplo de Análisis LR Gramática 1. E::= E + T 2. E::= T 3. T::= T * F 4. T::= F 5. F::= ( E ) 6. F::= Id Tabla de análisis sintáctico Acción Ir_a Estado Id + * ( ) $ E T F 0 d5 d4 1 2 3 1 d6 ACP 2 r2 d7 r2 r2 3 r4 r4 r4 r4 4 d5 d4 8 2 3 5 r6 r6 r6 r6 6 d5 d4 9 3 7 d5 d4 10 8 d6 d11 9 r1 d7 r1 r1 10 r3 r3 r3 r3 11 r5 r5 r5 47 r5 Ejemplo de Análisis LR 48 Pila Entrada Acción 0 Id * Id + Id $ d5 0 Id 5 * Id + Id $ r6 0 F 3 * Id + Id $ r4 0 T 2 * Id + Id $ d7 0 T 2 * 7 Id + Id $ d5 0 T 2 * 7 Id 5 + Id $ r6 0 T 2 * 7 F 10 + Id $ r3 0 T 2 + Id $ r2 0 E 1 + Id $ d6 0 E 1 + 6 Id $ d5 0 E 1 + 6 Id 5 $ r6 0 E 1 + 6 F 3 $ r4 0 E 1 + 6 T 9 $ r1 0 E 1 $ ACP 24

Construcción de una Tabla LR 49 Definiciones Item (elemento) Producción con un marcador de posición S::= if C then S En la entrada se ha visto el token if y queda por procesar C then S Estado Representa un momento en la derivación, equivale a un estado en el autómata que realiza el análisis Un estado está formado por un conjunto de items 50 Algoritmo de definición de estados Crear un símbolo no terminal nuevo S Crear una nueva producción S ::=S, donde es el axioma Crear el estado inicial, S 0 ={(S ::= S)} Mientras se creen nuevos estados hacer Cierre: Si A::=x X S i entonces, Para cada X::=w P Creación S i =S i U {(X::= w)} Para cada z I i =(A::=x zw) S i Crear un nuevo estado S j ={(A::=xz w)} Para cada I k =(B::= z) S i, I k I i S j =S j U {(B::= z)} 25

Algoritmo de tabla SLR(1) 51 Desplazar Si A::=x aw S i, A::=xa w S j, a T Entonces Acción[S i,a]=desplazar S j Reducir Si A::=w S i, P j =(A::=w) Entonces Para cada a SIGUIENTE(A) Acción [S i,a]=reducir j Aceptar Si S ::=S S i Entonces Acción[S i,$]=aceptar Ir_a Si A::=x Bw S i, A::=xB w S j, B N Entonces Ir_a[S i,b]= S j 52 Análisis Sintáctico: Manejo de Errores Características Informar con claridad y exactitud Recuperación rápida No debe retrasar el procesamiento de programas sin errores Estrategias de recuperación Modo de pánico Nivel de frase Producciones de error Corrección Global 26

53 Estrategias de recuperación de errores (I) Modo de pánico Método más sencillo Lo pueden utilizar la mayoría de los métodos de análisis FUNCIONAMIENTO: Desecha los símbolos de entrada hasta que encuentra componentes léxicos de sincronización (delimitadores, punto y coma, end) Adecuado para lenguajes en los que es raro que se produzcan varios errores en la misma línea Nivel de frase FUNCIONAMIENTO: Realizar una corrección local de la entrada restante para poder continuar con el análisis, (sustituir coma por punto y coma, añadir coma) Dificultad para manejar situaciones en las que el error se produjo antes del punto de detección 54 Estrategias de recuperación de errores (II) Producciones de error FUNCIONAMIENTO Si se conocen los errores que pueden suceder, entonces puede extenderse la gramática para incluir producciones de error Corrección global FUNCIONAMIENTO Son algoritmos que minimiza el número de cambios necesarios para convertir una cadena errónea en otra correcta Demasiado costoso, en tiempo y espacio Solo tiene interés teórico 27