La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Compiladores e intérpretes Análisis Sintáctico II

Presentaciones similares


Presentación del tema: "Compiladores e intérpretes Análisis Sintáctico II"— Transcripción de la presentación:

1 Compiladores e intérpretes Análisis Sintáctico II
Profesor: Eridan Otto

2 Análisis Sintáctico II
Parser Predictivo Parser Recursivo descendente Parser Predictivo norecursivo

3 Análisis sintáctico II: backtracking
Compiladores e intérpretes Análisis sintáctico II: backtracking Si no se factoriza puede ser necesario hacer backtracking, en un parser descendente recursivo. Ejemplo: sea la gramática S::= cAd A::=ab|a El parser debe reconocer w=cad Primer intento S -> cAd ->cabd se solicita el póximo token d <>b por lo que el parser debe retroceder hasta la primera drivación: Secundo intento S->cAd->cad. Ahora si el reconocimiento es exitoso

4 Análisis sintáctico II: AS predictivo
Compiladores e intérpretes Análisis sintáctico II: AS predictivo No necesita realizar retroceso para analizar correctamente 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: Gramática bien diseñada Eliminación de la recursividad izquierda Factorizar por la izquierda A pesar de las acciones anteriores no está garantizada una gramática predictiva Las gramáticas pueden llegar a ser difíciles de leer Para las partes gramaticales que no son predictivas se pueden utilizar otros analizadores

5 Análisis sintáctico II: AS predictivo,descendente recursivo
Compiladores e intérpretes Análisis sintáctico II: AS 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 Existe una variable que contene el próximo token a analizar Se define una función FIRST( ) que genera el conjunto de tokens que aparecen como los primeros símbolos de un no terminal o una cadena generada por Si es , entonces también está en FIRST( ) Luego se verá más en detalle esta función. Ejemplo: tipo ::= simple | ^id|array [simple] of tipo simple ::= integer | char | num puntopunto num FIRST(simple) = {integer , char ,num} FIRST(^id) = {^} FIRST(array [simple] of tipo d) = {array}

6 Análisis sintáctico II: AS predictivo,descendente recursivo
Compiladores e intérpretes Análisis sintáctico II: AS predictivo,descendente recursivo El conjunto FIRST debe ser considerado si hay dos producciones A::= y A::= El parser recursivo descendente requiere, para no hacer retroceso, que FIRST( ) y FIRST( ) sean conjuntos disjuntos. Entonces el próximo símbolo puede ser usado para decidir qué producción usar. Producciones - Las producciones con en el lado derecho requieren tratamiento especial, el parser descendente recursivo usa las producciones- por defecto cuando ninguna otra producción puede ser usada. Por ejemplo la siguiente gramática: sentencia ::= begin sentencias_optat end sentencias_optat ::= lista_sentencias | Cuando se está analizando sentencias_optat , si el próximo token no está en el FIRST(sentencias_optat), entonces la producción es usada . Esta elección es correcta si el próximo símbolo es end. Cualquier otro próximo token distinto de end resultará en un error, detectado durante el análisis de sentencia

7 Análisis sintáctico II: AS predictivo,descendente recursivo
Compiladores e intérpretes Análisis sintáctico II: AS predictivo,descendente recursivo En un parser descendente recursivo, cada procedimiento hace dos cosas Decide la producción que utilizará analizando el símbolo de próximo token o preanálisis. Si el símbolo está en FIRST( ), entonces se usa la producción con el lado derecho de . Una producción con en el lado derecho es usada si el símbolo de preanálisis no está en el conjunto FIRST de ninguno de los otros lados derechos de la producción. Usa una producción imitando al lado derecho. Un no terminal da como resultado una llamada a otro procedimiento (recordar cada proedimientocorresponde a un no terminal). Un terminal o token , que coincide con el símbolo de preanálisis, produce la lectura del siguiente token. Si , en un cierto punto, ningún token alternativo en el procedimiento coincide, entonces se produce un error. La secuencia de procedimientos invocados al procesar la entrada define implícitamente un árbol de análisis sintáctico.

8 Análisis sintáctico II: AS predictivo,descendente recursivo
Compiladores e intérpretes Análisis sintáctico II: AS predictivo,descendente recursivo Ejemplo:Para la gramática simple de tipos escriba pseudocódigo de un parser descendente recursivo (*procedimiento para leer el próximo token y hacer verificaciones*) Procedimiento scan(t:token) Inicio si preanalisis = t entonces (*variable con el próximo símbolo global*) preanalisis := yylex() sino error() Fin Procedimiento tipo; si preanalisis en (integer , char ,num) entonces simple sino si preanalisis = ^ entonces inicio scan(^);scan(id) fin

9 Análisis sintáctico II: AS predictivo,descendente recursivo
Compiladores e intérpretes Análisis sintáctico II: AS predictivo,descendente recursivo sino si preanalisis = array entonces inicio scan(array);scan([); simple; scan(]);scan(of); tipo Fin Sino error() Fin; Procedimiento simple ; Inicio si preanalisis = integer entonces scan(integer) sino si preanalisis = char entonces scan(char ) sino si preanalisis = num entonces inicio scan(num ); scan(puntopunto ); scan(num ); fin sino error()

10 Análisis sintáctico II: AS predictivo,descendente recursivo
Compiladores e intérpretes Análisis sintáctico II: AS predictivo,descendente recursivo Ejercicio:escriba pseudocódigo de un parser descendente recursivo Para la siguiente parte de una gramática, asuma que ya tiene construida el procedimiento scan: Sent ::= if exp then Sent | write exp | id := exp exp ::= id=id | id<>id | true|false

11 Análisis sintáctico II: AS predictivo,descendente recursivo
Compiladores e intérpretes Análisis sintáctico II: AS predictivo,descendente recursivo Procedimiento Sent; Inicio si preanalisis = if entonces inicio scan(if); exp; scan(then); Sent; fin sino si preanalisis = write entonces inicio scan(write); exp; sino si preanalisis = id entonces inicio scan(id); scan(:=); exp; sino error()

12 Análisis sintáctico II: AS predictivo,descendente recursivo
Compiladores e intérpretes Análisis sintáctico II: AS predictivo,descendente recursivo Procedimiento exp; Inicio si preanalisis = id entonces scan(id) si preanalisis = igual entonces inicio scan(igual); scan(id); fin sino si preanalisis = <> entonces inicio scan(<>); scan(id); sino si preanalisis = true entonces scan(true ); sino si preanalisis = false entonces sino error()

13 Análisis sintáctico II: parser predictivo,no recursivo
Compiladores e intérpretes Análisis sintáctico II: parser predictivo,no recursivo Es posible construir un parser predictivo no recursivo , manteniendo un stack en forma explícita , más que implícitamente via llamadas recursivas. que son ineficientes y poco controlables. El problema clave durante el parser predictivo es la determinación de la producción a ser aplicada para un no terminal. El parser no recursivo de la figura extrae la producción a ser aplicada de una tabla de análisis. En la próxima clase se verá como la tabla puede ser construida de ciertas gramáticas a + b $ X Parser predictivo Y Z $ Tabla de parser


Descargar ppt "Compiladores e intérpretes Análisis Sintáctico II"

Presentaciones similares


Anuncios Google