Análisis Sintáctico Descendente CI4721 – Lenguajes de Programación II Ernesto Hernández-Novich <[email protected]> Universidad “Simón Bolívar” Copyright ©2012-2016 Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 1 / 27 Motivación Reconocedor descendente no determinístico Sea G = (N, Σ, P, S) una CFG cualquiera. Entonces el PDA extendido Desc(G) = ({q0 , q1 }, Σ, N ∪ Σ, δ, q0 , {q1 }) con δ definida según δ(q0 , λ, λ) = {(q1 , S)} (1) δ(q1 , λ, A) = {A → α ∈ P : (q1 , α)}, ∀A ∈ N (2) δ(q1 , a, a) = {(q1 , λ)}, ∀a ∈ Σ (3) ¿Cuál es la razón del no-determinismo? Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 2 / 27 Motivación Eliminando la ambigüedad “Husmear” antes de decidir • El reconocedor pretende encontrar ∗ S ⇒ w Left • En cualquier forma sentencial intermedia ∗ S ⇒ uAα Left es natural que u sea un prefijo de w . • Como w = uax podemos “espiar” a y eso ayuda . . . • . . . a decidir cuál regla A → wi expandir. • . . . a notar que ninguna regla aplica – ¡Error de sintaxis! Vamos a generalizar el “espiar”. Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 3 / 27 Lookahead “Espiar” es el nombre técnico para “lookahead” ¿Qué podemos obtener de un no terminal? Sea G = (N, Σ, P, S) libre de contexto y A ∈ N. Definimos el lookahead de A como ∗ ∗ LA(A) = {x |S ⇒ uAα ⇒ ux ∈ Σ∗ } Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 4 / 27 Lookahead “Espiar” es el nombre técnico para “lookahead” ¿Qué podemos obtener de un no terminal? Sea G = (N, Σ, P, S) libre de contexto y A ∈ N. Definimos el lookahead de A como ∗ ∗ LA(A) = {x |S ⇒ uAα ⇒ ux ∈ Σ∗ } LA(A) está constituido por todas las cadenas de terminales derivables a partir de Aα cuando uAα es una forma sentencial más izquierda. Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 4 / 27 Lookahead “Espiar” es el nombre técnico para “lookahead” ¿Qué podemos obtener de una regla particular? Sea G = (N, Σ, P, S) libre de contexto y A ∈ N. Definimos el lookahead de la regla A → α ∈ P como ∗ ∗ LA(A → α) = {x |αβ ⇒ x ∈ Σ∗ ∧ S ⇒ uAβ} Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 5 / 27 Lookahead “Espiar” es el nombre técnico para “lookahead” ¿Qué podemos obtener de una regla particular? Sea G = (N, Σ, P, S) libre de contexto y A ∈ N. Definimos el lookahead de la regla A → α ∈ P como ∗ ∗ LA(A → α) = {x |αβ ⇒ x ∈ Σ∗ ∧ S ⇒ uAβ} ∗ LA(A → α) ⊆ LA(A) en el cual las derivaciones Aβ ⇒ x comienzan expandiendo la regla A → α. Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 5 / 27 Lookahead El conjunto y sus partes Sean A → α1 , . . . A → αn las reglas para A, si se cumple 1 LA(A) = n S LA(A → αi ) i=1 2 LA(A → αi ) ∩ LA(A → αj ) = ∅ cuando 1 ≤ i < j ≤ n decimos que los LA(A → αi ) particionan LA(A) Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 6 / 27 Lookahead El conjunto y sus partes Sean A → α1 , . . . A → αn las reglas para A, si se cumple 1 LA(A) = n S LA(A → αi ) i=1 2 LA(A → αi ) ∩ LA(A → αj ) = ∅ cuando 1 ≤ i < j ≤ n decimos que los LA(A → αi ) particionan LA(A) • La primera condición siempre se cumple para una gramática libre de contexto directamente por la definición de LA(A). ∗ • Si la segunda condición se cumple, y tenemos S ⇒ uAβ tratando de derivar w = ux , entonces: • x es elemento de exactamente uno de los LA(A → α) – tenemos la regla a expandir. • x no pertenece a ninguno de los LA(A → α) – es imposible derivar w . Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 6 / 27 Lookahead Un ejemplo trivial . . . ¿Cómo expandir el no terminal S? Para el no-terminal S tenemos S → Aabd S → cAbcd A→a A→b A→λ Hernández-Novich (USB) LA(S) = {aabd, babd, abd, cabcd, cbbcd, cbcd} partido por los conjuntos LA(S → Aabd) = {aabd, babd, abd} LA(S → cAbcd) = {cabcd, cbbcd, cbcd} Análisis Sintáctico Descendente 2016 7 / 27 Lookahead Un ejemplo trivial . . . ¿Cómo expandir el no terminal S? Para el no-terminal S tenemos S → Aabd S → cAbcd A→a A→b A→λ LA(S) = {aabd, babd, abd, cabcd, cbbcd, cbcd} partido por los conjuntos LA(S → Aabd) = {aabd, babd, abd} LA(S → cAbcd) = {cabcd, cbbcd, cbcd} Basta lookahead de un símbolo para determinar cuál regla S expandir en cada caso. Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 7 / 27 Lookahead Un ejemplo trivial . . . ¿Cómo expandir el no terminal A? Para el no-terminal A tenemos S → Aabd LA(A) = {aabd, abcd, babd, bbcd, abd, bcd} S → cAbcd partido por los conjuntos A→a A→b A→λ Hernández-Novich (USB) LA(A → a) = {aabd, abcd} LA(A → b) = {babd, bbcd} LA(A → λ) = {abd, bcd} Análisis Sintáctico Descendente 2016 8 / 27 Lookahead Un ejemplo trivial . . . ¿Cómo expandir el no terminal A? Para el no-terminal A tenemos S → Aabd LA(A) = {aabd, abcd, babd, bbcd, abd, bcd} S → cAbcd partido por los conjuntos A→a A→b A→λ LA(A → a) = {aabd, abcd} LA(A → b) = {babd, bbcd} LA(A → λ) = {abd, bcd} Hace falta lookahead de tres símbolos para determinar cuál regla A expandir en cada caso. Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 8 / 27 Lookahead Si la gramática no es trivial . . . • Tanto LA(A) como LA(A → α) pueden contener cadenas de longitud arbitraria . . . • . . . y una cantidad arbitraria de cadenas. • El lookahead termina siendo un prefijo más corto que permita distinguir el LA(A → α) de interés. Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 9 / 27 Lookahead Prefijos de longitud k Sea G = (N, Σ, P, S) y k > 0 ∈ N definiremos la función trunck :: Σ∗ → Σ∗ llamada prefijo de longitud k como ( trunck (w ) = Hernández-Novich (USB) w u if |w | ≤ k if w = uv ∧ |u| = k Análisis Sintáctico Descendente 2016 10 / 27 Lookahead Prefijos de longitud k Sea G = (N, Σ, P, S) y k > 0 ∈ N definiremos la función trunck :: Σ∗ → Σ∗ llamada prefijo de longitud k como ( trunck (w ) = w u if |w | ≤ k if w = uv ∧ |u| = k que podemos extender a conjuntos trunck :: P(Σ∗ ) → P(Σ∗ ) como trunck (X ) = {trunck (w )|w ∈ X } Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 10 / 27 Lookahead Lookahead de longitud k Sea G = (N, Σ, P, S) y k > 0 ∈ N definiremos • Lookahead de A de longitud k LAk (A) = trunck (LA(A)) • Lookahead de la regla A → α de longitud k LAk (A → α) = trunck (LA(A → α)) Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 11 / 27 Lookahead Lookahead de longitud k Sea G = (N, Σ, P, S) y k > 0 ∈ N definiremos • Lookahead de A de longitud k LAk (A) = trunck (LA(A)) • Lookahead de la regla A → α de longitud k LAk (A → α) = trunck (LA(A → α)) Aún necesitamos un método más eficiente para calcular los LAk Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 11 / 27 FIRST y FOLLOW FIRST – Prefijos derivables de A Sea G = (N, Σ, P, S) y k > 0 ∈ N. Entonces, ∀α ∈ (N ∪ Σ)∗ definiremos ∗ FIRSTk (α) = trunck ({w |α ⇒ w }) Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 12 / 27 FIRST y FOLLOW FIRST – Prefijos derivables de A Sea G = (N, Σ, P, S) y k > 0 ∈ N. Entonces, ∀α ∈ (N ∪ Σ)∗ definiremos ∗ FIRSTk (α) = trunck ({w |α ⇒ w }) Lemma 1 FIRSTk (λ) = {λ} Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 12 / 27 FIRST y FOLLOW FIRST – Prefijos derivables de A Sea G = (N, Σ, P, S) y k > 0 ∈ N. Entonces, ∀α ∈ (N ∪ Σ)∗ definiremos ∗ FIRSTk (α) = trunck ({w |α ⇒ w }) Lemma 1 FIRSTk (λ) = {λ} 2 FIRSTk (a) = {a} Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 12 / 27 FIRST y FOLLOW FIRST – Prefijos derivables de A Sea G = (N, Σ, P, S) y k > 0 ∈ N. Entonces, ∀α ∈ (N ∪ Σ)∗ definiremos ∗ FIRSTk (α) = trunck ({w |α ⇒ w }) Lemma 1 FIRSTk (λ) = {λ} 2 FIRSTk (a) = {a} 3 FIRSTk (aα) = {aw |w ∈ FIRSTk−1 (α)} Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 12 / 27 FIRST y FOLLOW FIRST – Prefijos derivables de A Sea G = (N, Σ, P, S) y k > 0 ∈ N. Entonces, ∀α ∈ (N ∪ Σ)∗ definiremos ∗ FIRSTk (α) = trunck ({w |α ⇒ w }) Lemma 1 FIRSTk (λ) = {λ} 2 FIRSTk (a) = {a} 3 FIRSTk (aα) = {aw |w ∈ FIRSTk−1 (α)} 4 FIRSTk (αβ) = trunck (FIRSTk (α)FIRSTk (β)) Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 12 / 27 FIRST y FOLLOW FIRST – Prefijos derivables de A Sea G = (N, Σ, P, S) y k > 0 ∈ N. Entonces, ∀α ∈ (N ∪ Σ)∗ definiremos ∗ FIRSTk (α) = trunck ({w |α ⇒ w }) Lemma 1 FIRSTk (λ) = {λ} 2 FIRSTk (a) = {a} 3 FIRSTk (aα) = {aw |w ∈ FIRSTk−1 (α)} 4 FIRSTk (αβ) = trunck (FIRSTk (α)FIRSTk (β)) 5 Si A → α ∈ P entonces FIRSTk (α) ⊆ FIRSTk (A) Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 12 / 27 FIRST y FOLLOW Calculando FIRSTk FIRST1 (S) = {a, b, c} S → Aabd S → cAbcd A→a A→b A→λ FIRST1 (A) = {a, b, λ} FIRST2 (S) = {aa, ba, ab, ca, cb} FIRST2 (A) = {a, b, λ} FIRST3 (S) = {aab, bab, abd, cab, cbb, cbc} FIRST3 (A) = {a, b, λ} Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 13 / 27 FIRST y FOLLOW FOLLOW – Prefijos que continúan derivaciones de A Sea G = (N, Σ, P, S) y k > 0 ∈ N. Entonces, ∀A ∈ N definiremos ∗ FOLLOWk (A) = {x |S ⇒ uAα ∧ x ∈ FIRSTk (α)} Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 14 / 27 FIRST y FOLLOW FOLLOW – Prefijos que continúan derivaciones de A Sea G = (N, Σ, P, S) y k > 0 ∈ N. Entonces, ∀A ∈ N definiremos ∗ FOLLOWk (A) = {x |S ⇒ uAα ∧ x ∈ FIRSTk (α)} Lemma 1 λ ∈ FOLLOWk (S) Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 14 / 27 FIRST y FOLLOW FOLLOW – Prefijos que continúan derivaciones de A Sea G = (N, Σ, P, S) y k > 0 ∈ N. Entonces, ∀A ∈ N definiremos ∗ FOLLOWk (A) = {x |S ⇒ uAα ∧ x ∈ FIRSTk (α)} Lemma 1 λ ∈ FOLLOWk (S) 2 Si A → αB ∈ P entonces FOLLOWk (A) ⊆ FOLLOWk (B) Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 14 / 27 FIRST y FOLLOW FOLLOW – Prefijos que continúan derivaciones de A Sea G = (N, Σ, P, S) y k > 0 ∈ N. Entonces, ∀A ∈ N definiremos ∗ FOLLOWk (A) = {x |S ⇒ uAα ∧ x ∈ FIRSTk (α)} Lemma 1 λ ∈ FOLLOWk (S) 2 Si A → αB ∈ P entonces FOLLOWk (A) ⊆ FOLLOWk (B) 3 Si A → αBβ ∈ P entonces trunck (FIRSTk (β)FOLLOWk (A)) ⊆ FOLLOWk (B) Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 14 / 27 FIRST y FOLLOW Calculando FOLLOWk FOLLOW1 (S) = {λ} S → Aabd S → cAbcd A→a A→b A→λ FOLLOW1 (A) = {a, b} FOLLOW2 (S) = {λ} FOLLOW2 (A) = {ab, bc} FOLLOW3 (S) = {λ} FOLLOW3 (A) = {abd, bcd} Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 15 / 27 FIRST y FOLLOW Podemos calcular los lookaheads Theorem Sea G = (N, Σ, P, S). Para todo k > 0 ∈ N, A ∈ N y A → α ∈ P podemos calcular 1 LAk (A) = trunck (FIRSTk (A)FOLLOWk (A)) 2 LAk (A → α) = trunck (FIRSTk (α)FOLLOWk (A)) Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 16 / 27 FIRST y FOLLOW Podemos calcular los lookaheads Theorem Sea G = (N, Σ, P, S). Para todo k > 0 ∈ N, A ∈ N y A → α ∈ P podemos calcular 1 LAk (A) = trunck (FIRSTk (A)FOLLOWk (A)) 2 LAk (A → α) = trunck (FIRSTk (α)FOLLOWk (A)) Como α = r1 r2 . . . rn siendo ri ∈ (N ∪ Σ), entonces LAk (A → α) = trunck (FIRSTk (α)FOLLOWk (A)) = trunck (FIRSTk (r1 ) . . . FIRSTk (rn )FOLLOWk (A)) Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 16 / 27 FIRST y FOLLOW Calculando LAk usando FIRSTk y FOLLOWk S → Aabd S → cAbcd A→a A→b A→λ LA3 (S → Aabd) = trunc3 (FIRST3 (A)FIRST3 (a)FIRST3 (b)FIRST3 (d)FOLLOW3 (S)) = trunc3 ({a, b, λ}{a}{b}{d}{λ}) = trunc3 ({aabd, babd, abd}) = {aab, bab, abd} Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 17 / 27 Gramáticas fuertemente LL(k) Gramática Fuertemente LL(k) Sea G = (N, Σ, P, S) con marcador de final (endmarker) $k . Diremos que G es fuertemente LL(k) si siempre que existan dos derivaciones más izquierdas ∗ ∗ ∗ ∗ S ⇒ u1 Aα1 ⇒ u1 βα1 ⇒ u1 zv1 S ⇒ u2 Aα2 ⇒ u2 γα2 ⇒ u2 zv2 con ui , vi , z ∈ Σ∗ y |z| = k, entonces β = γ. Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 18 / 27 Gramáticas fuertemente LL(k) Gramática Fuertemente LL(k) Sea G = (N, Σ, P, S) con marcador de final (endmarker) $k . Diremos que G es fuertemente LL(k) si siempre que existan dos derivaciones más izquierdas ∗ ∗ ∗ ∗ S ⇒ u1 Aα1 ⇒ u1 βα1 ⇒ u1 zv1 S ⇒ u2 Aα2 ⇒ u2 γα2 ⇒ u2 zv2 con ui , vi , z ∈ Σ∗ y |z| = k, entonces β = γ. • El marcador $k se agrega a todas las entradas para garantizar que siempre habrá k símbolos en el lookahead. • Si S no es recursivo, se agrega $k al final de cada regla de S. • Si S es recursivo, se agrega la regla S 0 → S$k Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 18 / 27 Gramáticas fuertemente LL(k) Relación con los lookaheads Theorem G es fuertemente LL(k) ⇔ ∀A ∈ N, LAk (A → αi ) particionan LAk (A) Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 19 / 27 Gramáticas fuertemente LL(k) Relación con los lookaheads Theorem G es fuertemente LL(k) ⇔ ∀A ∈ N, LAk (A → αi ) particionan LAk (A) Demostración (⇐). 1 Supongamos que LAk (A → αi ) particionan LAk (A). Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 19 / 27 Gramáticas fuertemente LL(k) Relación con los lookaheads Theorem G es fuertemente LL(k) ⇔ ∀A ∈ N, LAk (A → αi ) particionan LAk (A) Demostración (⇐). 1 Supongamos que LAk (A → αi ) particionan LAk (A). 2 Sea z ∈ Σ∗ con |z| = k que aparece en dos derivaciones ∗ ∗ ∗ ∗ S ⇒ u1 Aα1 ⇒ u1 βα1 ⇒ u1 zv1 S ⇒ u2 Aα2 ⇒ u2 γα2 ⇒ u2 zv2 Así, z ∈ LAk (A → β) y z ∈ LAk (A → γ) Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 19 / 27 Gramáticas fuertemente LL(k) Relación con los lookaheads Theorem G es fuertemente LL(k) ⇔ ∀A ∈ N, LAk (A → αi ) particionan LAk (A) Demostración (⇐). 1 Supongamos que LAk (A → αi ) particionan LAk (A). 2 Sea z ∈ Σ∗ con |z| = k que aparece en dos derivaciones ∗ ∗ ∗ ∗ S ⇒ u1 Aα1 ⇒ u1 βα1 ⇒ u1 zv1 S ⇒ u2 Aα2 ⇒ u2 γα2 ⇒ u2 zv2 Así, z ∈ LAk (A → β) y z ∈ LAk (A → γ) 3 Como LAk (A → αi ) particionan LAk (A), entonces β = γ Por tanto, G es fuertemente LL(k). Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 19 / 27 Gramáticas fuertemente LL(k) Relación con los lookaheads Theorem G es fuertemente LL(k) ⇔ ∀A ∈ N, LAk (A → αi ) particionan LAk (A) Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 20 / 27 Gramáticas fuertemente LL(k) Relación con los lookaheads Theorem G es fuertemente LL(k) ⇔ ∀A ∈ N, LAk (A → αi ) particionan LAk (A) Demostración (⇒). 1 Supongamos que G es fuertemente LL(k) y sea z ∈ LAk (A). Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 20 / 27 Gramáticas fuertemente LL(k) Relación con los lookaheads Theorem G es fuertemente LL(k) ⇔ ∀A ∈ N, LAk (A → αi ) particionan LAk (A) Demostración (⇒). 1 Supongamos que G es fuertemente LL(k) y sea z ∈ LAk (A). 2 Entonces solamente existe una regla A que puede usarse a partir de formas sentenciales uAα para derivar cadenas uzw ∈ Σ∗ Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 20 / 27 Gramáticas fuertemente LL(k) Relación con los lookaheads Theorem G es fuertemente LL(k) ⇔ ∀A ∈ N, LAk (A → αi ) particionan LAk (A) Demostración (⇒). 1 Supongamos que G es fuertemente LL(k) y sea z ∈ LAk (A). 2 Entonces solamente existe una regla A que puede usarse a partir de formas sentenciales uAα para derivar cadenas uzw ∈ Σ∗ 3 Necesariamente z estará en exactamente un LAk (A → αi ). Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 20 / 27 Gramáticas fuertemente LL(k) Relación con los lookaheads Theorem G es fuertemente LL(k) ⇔ ∀A ∈ N, LAk (A → αi ) particionan LAk (A) Demostración (⇒). 1 Supongamos que G es fuertemente LL(k) y sea z ∈ LAk (A). 2 Entonces solamente existe una regla A que puede usarse a partir de formas sentenciales uAα para derivar cadenas uzw ∈ Σ∗ 3 Necesariamente z estará en exactamente un LAk (A → αi ). 4 En consecuencia los LAk (A → αi ) particionan LAk (A). Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 20 / 27 Gramáticas fuertemente LL(k) Ambigüedad gramatical Theorem Si G es fuertemente LL(k) para algún k entonces G no es ambigua. • El reconocedor para la gramática es determinístico – Hay exactamente una regla aplicable para cada paso de derivación. • La demostración queda como ejercicio. Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 21 / 27 Algoritmos Algoritmo de cálculo de FIRSTk Inicialización input: G = (N, Σ, P, S) CFG { Aplicación del Lema 2 de FIRST } for each a ∈ Σ do F 0 (a) ← {a} end for { El FIRST de un no terminal comienza vacío o con λ si hay una λ-producción – Aplicación del Lema 1 de FIRST } for each A ( ∈ N do {λ} if A → λ ∈ P F (A) ← ∅ otherwhise end for Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 22 / 27 Algoritmos Algoritmo de cálculo de FIRSTk Cómputo repeat {Conservar conjuntos de la iteración anterior} for each A ∈ N do F 0 (A) ← F (A) end for {Actualizar FIRST para todo A aplicando el Lema 4 para FIRST } for each A → u1 u2 . . . un with n > 0 do F (A) ← F (A) ∪ trunck (F 0 (u1 )F 0 (u2 ) . . . F 0 (uk )) end for {Detenerse cuando deje de haber actualizaciones} until F (A) = F 0 (A) for all A ∈ N output: FIRSTk (A) = F (A) Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 23 / 27 Algoritmos Algoritmo de cálculo de FOLLOWk Inicialización inputs: G = (N, Σ, P, S) y FIRSTk (A) for all A ∈ N { Aplicación del Lema 1 para FOLLOW } FL(S) ← {λ} { El FOLLOW del resto de los no terminales comienza vacío } for each A ∈ N − {S} do FL(A) ← ∅ end for Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 24 / 27 Algoritmos Algoritmo de cálculo de FOLLOWk Cómputo repeat {Conservar conjuntos de la iteración anterior} for each A ∈ N do FL0 (A) ← FL(A) end for for each A → w = u1 u2 . . . un do { Aplicación del Lema 2 para FOLLOW } L ← FL0 (A) if un ∈ N then FL(un ) ← FL(un ) ∪ L end if { Aplicación del Lema 3 para FOLLOW } for i = n − 1 to 1 do L ← trunck (FIRSTk (ui+1 )L) if ui ∈ N then FL(ui ) ← FL(ui ) ∪ L end if end for end for until FL(A) = FL0 (A) for all A ∈ N output: FOLLOWk (A) = FL(A) Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 25 / 27 Consideraciones Consideraciones • Una gramática ambigüa no puede ser fuertemente LL(k). • Demuestre que una gramática que contiene producciones de la forma A → aα A → aβ con α 6= β, no puede ser fuertemente LL(1). ¿Puede encontrar alguna condición para generalizar a LL(k)? • Demuestre que una gramática que incluye algún no terminal A recursivo por izquierda no puede ser fuertemente LL(k) para ningún k > 0. Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 26 / 27 Referencias Bibliográficas Bibliografía • [Sudkamp] • Secciones 19.1 a 19.6 • Ejercicios 19.2 a 19.6 • Practique las técnicas de transformación de gramáticas que permiten factorizar producciones por izquierda y eliminar la recursión izquierda generalizada. Hernández-Novich (USB) Análisis Sintáctico Descendente 2016 27 / 27