i = 1;
i = i + 2;
Figura 1: Arbol de derivación
Todos los lenguajes de programación se definen recursivamente:
Una gramática libre de contexto consiste en:
Figura 3: Fases de la compilación
Supongamos que la gramática es:
y la entrada es \((())\).
El problema ahora es construir un árbol de derivación de forma que las hojas correspondan a la entrada.
Una derivación que me genera la palabra
y con la derivación puedo construir el árbol de derivación.
¿Cómo consigo el árbol de derivación directamente?
Los analizadores LL recorren los datos de izquierda a derecha y construyen la derivación izquierda: en cada momento, la pila contiene lo que se espera ``encontrar'' en la cinta.
Los sucesivos pasos del analizador van leyendo la cinta y va modificando la pila para que tenga un resumen de lo que queda por ver.
Figura 7: Parseo LL
La principal ventaja de los analizadores descendentes es que pueden ser construidos ``fácilmente'', en un programa utilizando recursividad.
También que permiten detectar errores e informar al usuario de donde esta exactamente el error.
La desventaja es que necesitan gramáticas que tengan buenas propiedades.
Existe una estrategia alternativa: el análisis LR, que recorre los datos de izquierda a derecha pero construye la derivación derecha.
Sólo que la hemos de construir ``al revés'', empezando por el final: en cada momento, la concatenación del contenido de la pila con lo que queda por leer reconstruyen una derivación a la derecha de la palabra en orden inverso.
Vamos a definir dos símbolos:
y dos operaciones básicas:
Nuestros autómatas con pila van a poder:
Colocar € en el fondo de pila: