Universidad Simón Bolívar Departamento de Computación y Tecnología de la Información CI4721 – Lenguajes de Programación II Enero-Abril 2010 Carnet: Nombre: Examen I (35 puntos) Antes de empezar, revise bien el examen, el cual consta de cuatro preguntas. Pregunta 0 Pregunta 1 Pregunta 2 Pregunta 3 Total 15 puntos 5 puntos 5 puntos 10 puntos 35 puntos Pregunta 0 — 15 puntos Una gramática para un lenguaje de programación imperativo típico que incluya el clásico problema de ambigüedad del “dangling-else” contendría un segmento similar al siguiente: ··· Instr Instr Instr Cond ··· → if ( Cond ) Instr → if ( Cond ) Instr else Instr → ··· → ··· donde el resto de las producciones del símbolo no-terminal Instr corresponderían a instrucciones básicas y otras instrucciones compuestas, y las producciones del símbolo no-terminal Cond corresponderían a expresiones booleanas. Para simplificar el análisis del problema del “dangling-else”, hagamos abstracción de los detalles del segmento de gramática anterior y propongamos la siguiente gramática reducida G: ( { I 0 , I } , { i, e, b } , P , I 0 ) con P compuesto por las producciones I0 I I I → → → → I iI iIeI b donde el nuevo símbolo terminal i representa al anterior if y la expresión booleana parentizada que lo acompañaba, e representa al anterior else, y b representa a las anteriores instrucciones básicas y posibles otras instrucciones compuestas. Analicemos ahora el problema de la ambigüedad del “dangling-else” por medio de la gramática G, en el contexto del análisis sintáctico LR. (0.0) Construya la máquina característica determinística LR(1) para G. (0.1) Indique cuántos conflictos LR(1) contiene su máquina característica, y señale cómo deben ser manejados estos conflictos para dar la solución clásica al “dangling-else” ambiguo: asociar un else ambiguo al if abierto más reciente. (0.2) Explique cómo construiría la máquina característica LALR(1) para G a partir de la máquina característica LR(1), y diga cuántos estados menos tendría su nueva máquina. Pregunta 1 — 5 puntos Continuando con la gramática G de la pregunta anterior, está claro que ésta no puede ser LL(1) ya que dos de los lados derechos de producciones de I empiezan por el símbolo terminal i y, por lo tanto, ambas producciones tendrán como lookahead de tamaño 1 a i. Se desea aplicar “factorización izquierda” (left factoring) a G para intentar resolver este problema y analizar el resultado. (1.0) Muestre la gramática G0 resultante de aplicar “factorización izquierda” a G. (1.1) Muestre que G0 tampoco es LL(1), dando el conjunto de lookaheads de tamaño 1 de todas las producciones de G0 y señalando dónde hay conflicto. Nota: No hace falta que muestre cómo calcula Ud. los lookaheads de las producciones. Tiene libertad de hacer tal cálculo, y también el cálculo de “primeros” (first) y “siguientes” (follow ) si los necesita, de cualquier manera. Pregunta 2 — 5 puntos Sabemos que la técnica de análisis sintáctico LL no puede manejar recursión izquierda, ni directa ni indirecta. Se quiere que Ud. muestre que esto es efectivamente así para el caso de recursión izquierda directa. Específicamente, Ud. debe mostrar que en una gramática sin símbolos inútiles que cuente con dos producciones de la forma A → A α y A → β , estas dos producciones deben compartir al menos un lookahead-k para cualquier entero positivo k. Note la hipótesis sobre la inexistencia de símbolos inútiles en la gramática. Formalmente, en una gramática ( N , Σ , P , S ) un símbolo X es inútil si no puede construirse derivación alguna con las producciones de la gra∗ ∗ mática de la forma S ⇒ γ0 X γ1 ⇒ w , con γ0 , γ1 ∈ (N ∪ Σ)∗ y w ∈ Σ∗ . Puede utilizar todas las propiedades conocidas sobre lookahead-k, “primeros”-k y “siguientes”-k, en particular todas las propiedades presentadas en el texto “Languages and Machines” de Thomas Sudkamp (las cuales fueron también analizadas en clase). Pregunta 3 — 10 puntos Siendo G una gramática libre de contexto cualquiera ( N , Σ , P , S ) , conocemos el siguiente automáta de pila Asc(G) con el cual se puede hacer análisis sintáctico ascendente del lenguaje generado por G: ( { q0 , q1 } , Σ , N ∪ Σ , δ , q0 , { q1 } ) con δ definida como δ (q0 , a , λ) = { (q0 , a) } δ (q0 , λ , α) = { A : A → αR ∈ P : (q0 , A) } δ (q0 , λ , S) = { A : A → S ∈ P : (q0 , A) } ∪ { (q1 , λ) } para α 6= S . Se desea que Ud. muestre parcialmente que este autómata reconoce correctamente el lenguaje generado por G, respondiendo lo siguiente: n (3.0) Demuestre por inducción que para cualquier entero n tal que n > 0 se cumple que: si β ⇒ w es una derivación derecha (rightmost) en G entonces [ q0 , w v , λ ] `n+|w| [ q0 , v , β R ] corresponde a una secuencia de movimientos en Asc(G), para cualesquiera β ∈ (N ∪ Σ)∗ y w, v ∈ Σ∗ . (3.1) Demuestre que L(G) ⊆ L(Asc(G)) utilizando como lema a la parte anterior (aunque no la haya demostrado).