TEMA 2. ANÁLISIS SINTÁCTICO DESCENDENTE Familia de Analizadores LL(k) PROCESADORES DE LENGUAJES 4o Informática http://ccia.ei.uvigo.es/docencia/PL 2 de noviembre de 2007 – FJRP 2007 ccia PL – 2.1 Definiciones y conceptos LL(k): Tipo de gramáticas independientes del contexto (GIC) para las que se pueden construir analizadores deterministas descendentes. L: Left-to-right scan (lectura de izq. a derecha) R: Lefttmost derivation (derivación izquierda) k: no de sı́mbolos de anticipación (adelanto, look-ahead) Definición (Derivación por la izquierda) Dada una una GIC no ambigua G = (N, Σ, P, S) y dada una de las cadenas que genera, w = a1a2 . . . an ∈ L(G), existe una única secuencia de cadenas de sı́mbolos (formas sentencials), α0, α1, . .8 . , αm, que conforma la derivación por la izquierda de > < α0 = S p i αi ⇒ αi+1 con pi ∈ P w, donde > : lm αm = w El análisis sintáctico de la cadena w vendrá dado por la secuencia de reglas: p0 , p1 , . . . , pm Definición intuitiva Una GIC G se dice que es LL(k) si en cualquier paso de derivación pi intermedio αi ⇒ αi+1, de la forma lm p i a1a2 . . . aj Aβ ⇒ a1a2 . . . aj γβ lm se puede determinar la regla a aplicar, pi = A → γ , conociendo: • el no terminal A • los siguientes k sı́mbolos de entrada: aj+1aj+2 . . . aj+k (terminales aún no analizados) Para las gramáticas de este tipo es posible construir analizadores deterministas que reconozcan las cadenas de entrada en tiempo lineal. – FJRP 2007 ccia PL – 1 Definición formal Definición (Conjunto firstk ) 8 ˛ ∗ ˛ α⇒ > xβ si |x| = k > ˛ < ˛ ∗ firstk (α) = x ∈ Σ ˛˛ ó > ∗ > ˛ α⇒ : x si |x| < k ˛ 9 > > = > > ; Conjunto de cadenas de terminales de longitud menor o igual que k que pueden aparecer al comienzo de las derivaciones de α (puede incluir ε) Definición (Gramática LL(k)) Sea G = (N, Σ, P, S) una GIC. Dadas dos derivaciones por la izquierda de la forma (reglas A → β ∈ P y A → γ ∈ P ): ∗ ∗ S ⇒ wAα ⇒ wβα ⇒ wx lm ∗ lm lm lm lm ∗ S ⇒ wAα ⇒ wγα ⇒ wy lm Diremos que G es una gramática LL(k) (k > 0) cuando verifica que si firstk (x) = firstk (y) entonces β = γ (las dos reglas son la misma) Es decir, en una gramática LL(k) no es posible que para un mismo sı́mbolo A haya 2 reglas distintas que puedan generar 2 derivaciones distintas que comiencen con los mismos k terminales. – FJRP 2007 ccia PL – 2 Definición (Gramática LL(1) Simple [SLL(1)]) Sea Sea G = (N, Σ, P, S) una GIC ε-libre. Si ∀A ∈ N , las reglas de derivación de A son de la forma A → aβ , siendo a ∈ Σ distinto en cada regla, entonces se dice que G es una gramática LL(1) simple (NOTACIÓN: SLL(1)) Nota: puede extenderse la definición a gramática LL(k) simple (SLL(k)) Teorema Sea G una gramática SLL(1) ⇒ G es una gramática LL(1) Ejemplo (Comprobación manual) La gramática G1 definida por las reglas » S → aAS S→b A→a A → bSA – » S→ε S → abA A → Saa A→b – es LL(1) La gramática G2 definida por las reglas no es LL(1), pero si es LL(2) – FJRP 2007 ccia PL – 3 2.2 Algoritmo de análisis LL(k) Algoritmos predictivos de análisis sintáctico descendente Las gramáticas LL(k) se adaptan especialmente a este tipo de algoritmos. Definición (Algoritmo k-predictivo) Dada una GIC G = (N, Σ, P, S), un algoritmo de análisis k-predictivo para G está constituido por: 1. una cinta de entrada 2. una pila 3. una cinta de salida 4. una tabla de análisis que controla el algoritmo Esquema: La salida del analizador es una traza (lista de reglas) de la derivación izquierda de la cadena de entrada La cabeza de lectura es capaz de acceder a los siguientes k sı́mbolos de la cinta de entrada (conforman la ventana o lookahead) La pila señala su fondo con el sı́mbolo especial $, que también marca el final de la cadena de entrada – FJRP 2007 ccia PL – 4 Definición (configuración, acción, movimiento) Dada una GIC G = (N, Σ, P, S) y el correspondiente algortimo k-predictivo a para G Una configuración de a es un triple (x, Xα, Π) donde 1. x es la porción de la cadena de entrada que queda por analizar 2. Xα es el contenido de la pila (con X en la cima) 3. Π es la cadena de salida actual Una ación en el algoritmo k-predictivo a viene dada por una tabla de análisis M [X, u] de la forma: M : (Γ ∪ {$}) × Σk → {quitar,aceptar,error, (β, i)} con Γ = N ∪ Σ, β ∈ Γ∗, i ∈ N, y pi = A → β ∈ P Un movimiento en a para una configuración (x, Xα, Π) viene definido por una entrada M [X, u], con u ∈ firstk (x), de la siguiente forma: • • • • M [X, u] = (β, i) ⇒ (x, Xα, Π) ` (x, βα, Πi) M [a, u] = quitar, (con x = ax0 ) ⇒ (ax0 , aα, Π) ` (x0 , α, Πi) M [X, u] = error ⇒ (x, Xα, Π) es config. de error (PARAR) M [$, ε] = error ⇒ (ε, $, Π) es config. de aceptación Dada w ∈ Σ∗, la configuración inicial de un algoritmo k-predictivo a es (x, X0$, ε), donde • w es la cadena a analizar • X0 es el sı́mbolo inicial de la pila (S ) ∗ Si (x, X0$, ε) ` (ε, $, Π) entonces no está definido. a(w) = Π; en otro caso a(w) Definimos la traducción definida por T[a] = {(w, Π) | a (T[a]) como el conjunto: a(w) = Π} Decimos que a es un algoritmo k-predictivo válido para una gramática G si y sólo si: a • L(G = {w ∈ Σ∗ | (w) está definido} • (w) = Π ⇒ Π es una análsis izquierdo de w a – FJRP 2007 ccia PL – 5 Ejemplo: Analizador 1-predictivo (1) (2) a para la gramática G definida por: S → aAS S→b (3) (4) A→a A → bSA . Tabla de análisis M [X, u] pila S A a b $ a aAS,1 a,3 quitar error error lookahead b ε b,2 error bSA,4 error error error quitar error error aceptar Analizar la cadena w = abbab (abbab, S$, ε) ` . . . – FJRP 2007 ccia PL – 6