Beruflich Dokumente
Kultur Dokumente
ANALIZADOR
SINTCTICO
ANALIZADOR SINTCTICO
1. INTRODUCCIN
El analizador lxico tiene como entrada el cdigo fuente en forma de una sucesin de caracteres.
El analizador sintctico tiene como entrada los lexemas que le suministra el analizador lxico y
su funcin es comprobar que estn ordenados de forma correcta (dependiendo del lenguaje que
queramos procesar). Los dos analizadores suelen trabajar unidos e incluso el lxico suele ser una
subrutina del sintctico. Al analizador sintctico se le suele llamar prser. El prser genera de
manera terica un rbol sintctico. Este rbol se puede ver como una estructura jerrquica que
para su construccin utiliza reglas recursivas. La estructuracin de este rbol hace posible
diferenciar entre aplicar unos operadores antes de otros en la evaluacin de expresiones. Es
decir, si tenemos esta expresin en Java:
x = x * y 2;
El valor de x depender de si aplicamos antes el operador producto que el operador suma. Una
manera adecuada de saber qu operador aplicamos antes es elegir qu rbol sintctico generar
de los dos posibles.
ANALIZADOR SINTCTICO
En resumen, la tarea del analizador sintctico es procesar los lexemas que le suministra el
analizador lxico, comprobar que estn bien ordenados, y si no lo estn, generar los informes
de error correspondientes. Si la ordenacin es correcta, se generar un rbol sintctico terico.
3. DISEO DE GRAMATICA
Para que un analizador sintctico funcione, debemos especificar el lenguaje que debe poder
leer. Para especificar este lenguaje, debemos representarlo con unas reglas nicas y bien
formadas de manera que el prser (Analizador sintctico) funcione de una manera bien definida.
Es decir, el lenguaje debe ser formal (tener unas reglas bien definidas). A estas reglas se le llama
gramtica. Por lo tanto, el primer paso para poder implementar un analizador sintctico es
definir la gramtica que debe ser capaz de analizar.
ANALIZADOR SINTCTICO
La gramtica que acepta el analizador sintctico es una gramtica de libre contexto, una
gramtica de libre contexto es una especificacin para la estructura sintctica de un lenguaje de
programacin. Una especificacin as es muy similar a la especificacin de la estructura lxica de
un lenguaje utilizando expresiones regulares(patrn), excepto que una gramtica libre de
contexto involucra reglas de recursividad. Una gramtica describe de forma natural la estructura
jerrquica de muchas construcciones de los lenguajes de programacin. Una gramtica libre de
contexto G queda definida por una tupla de cuatro elementos (N, T, P, S) donde:
N = No terminales. Elementos del lado izquierdo de produccin, antes de la flecha
T= Terminales. Elementos que no generan nada.
P= Reglas de produccin. Sentencias que se escriben en la gramtica. Cada regla o produccin
consta de:
E+T | T
T*F|F
id | F |(E)
ANALIZADOR SINTCTICO
Esta gramtica reconoce expresiones aritmticas con los operadores de suma y producto.
Vemos tambin que hay tres reglas y el axioma inicial es el antecedente de la primera regla de
produccin. E es recursiva porque se presenta en ambos lados de la produccin.
Ahora veamos con un ejemplo cmo podemos crear una gramtica. Para esto recodemos como
se declara una variable en java:
int a;
double b;
1) VAR -> TIPO ID;
2) TIPO -> int | double
3) ID - > id
DERIVACIN: Aplicacin de las reglas de producciones de una gramtica para obtener una
cadena de terminales.
Una regla de produccin puede considerarse como equivalente a una regla de reescritura,
donde el no terminal de la izquierda es sustituida por la pseudocadena del lado derecho de la
produccin. Podemos considerar que una pseudocadena es cualquier secuencia de terminales
y/o no terminales.
3 + 3 + 2 3 1 + 2 3
ANALIZADOR SINTCTICO
1 + 2 + 3
Hay dos posibles rboles sintcticos:
ANALIZADOR SINTCTICO
La raz del rbol es el axioma inicial y, segn nos convenga, lo dibujaremos en l a cima o en el
fondo del rbol. Como nodos internos del rbol, se sitan los elementos no terminales de las
reglas de produccin que vayamos aplicando, y cada uno de ellos poseer tantos hijos como
smbolos existan en la parte derecha de la regla aplicada.
4.
La recursividad se expresa por medio de una o ms reglas no recursivas, que son la base, y una
o ms reglas que son recursivas y que permiten hacer crecer la estructura del lenguaje
aplicndose a s mismas una y otra vez. Con un ejemplo, lo entenderemos mejor:
Supongamos que queremos expresar la estructura de un nmero entero compuesto por su signo
seguido por un nmero indeterminado de nmeros entre el 0 y el 9. Lo podramos expresar con
estas reglas:
Donde dgito representa cualquiera de los nmeros del 0 al 9. Mediante esas dos reglas
podemos representar la estructura de cualquier nmero entero sea de la longitud que sea.
Una gramtica se llama recursiva si es de la forma:
B. LA AMBIGEDAD
Cuando una gramtica contiene una cadena para la que hay ms de un rbol de anlisis
sintctico se dice que es ambigua. Debido a que una gramtica de estas caractersticas permite
que a partir del mismo cdigo fuente se puedan obtener diferentes cdigos intermedios, no es
vlida para construir un compilador (habra que ayudar con otras tcnicas ms complicadas).
Si una gramtica tiene alguna de estas caractersticas, podremos afirmar que es ambigua:
ANALIZADOR SINTCTICO
Gramticas con unas reglas que ofrezcan caminos alternativos entre dos puntos.
Por ejemplo:
ANALIZADOR SINTCTICO
SUPRESION DE LA AMBIGEDAD
A veces, una gramtica ambigua se puede reescribir para eliminar la ambigedad. Como
ejemplo, se eliminar la ambigedad de la siguiente gramtica con else ambiguo:
Aqu, otra representa cualquier otra proposicin. Esta gramtica es ambigua, puesto que la
cadena
1 2 1 2
Tiene los dos rboles de anlisis sintctico que se muestra a continuacin
Figura 4.2| Dos rboles de anlisis sintctico para una frase ambigua
ANALIZADOR SINTCTICO
En todo lenguaje de programacin con proposiciones condicionales de esta forma, se prefiere
el primer rbol de anlisis sintctico. La regla general es, emparejar cada else con el then sin
emparejar anterior ms cercano. Esta regla para eliminar ambigedades se puede incorporar
directamente a la gramatica. La ide es que una proposicin que aparezca entre un then si
emparejar seguido de cualquier proposicin, porque entonces el else estara obligado a
concordar con este then no emparejado. Una proposicin emparejada es o una proposicin ifthen-else que no contenga proposiciones sin emparejar o cualquier otra clase de proposicin
no condicional. As, se puede utilizar la gramtica
C. LA ASOCIATIVIDAD
La asociatividad es un concepto que aparece cuando se operan tres o ms operandos. La
asociatividad de un operador es por la izquierda si cuando aparecen tres o ms operandos se
evalan de izquierda a derecha. Si es de derecha a izquierda, la asociatividad es por la derecha.
Por ejemplo, si tenemos 6/3/2, por convencin es equivalente a (6/3) /2. Cuando un operando
como 3 tiene operadores a su izquierda y derecha, se necesitan convenciones para decir qu
operador considera ese operando. si el operador / tiene asociatividad por la izquierda,
primero se opera 6/3 el resultado se opera con 2 es 1.
Algunos operadores comunes, como el exponenciacin. Son asociativos por la derecha. Otro
ejemplo anlogo, el operador de asignacin = en java es asociativo por la derecha: en java, la
expresin a=b=c se trata igual que la expresin a=(b=c).
Las cadenas como a=b=c. Con un operador asociativo por la derecha. Son generados por la
siguiente gramtica:
=
El contraste entre un rbol de anlisis sintctico para un operador asociativo por la izquierda
como /, y un rbol de anlisis sintctico para un operador asociativo por la derecha como =,
El rbol de anlisis sintctico para 6/3/2 desciende hacia la izquierda, mientras que el rbol de
anlisis sintctico a=b=c desciende hacia la derecha.
La manera de reflejar la asociatividad de un operador en una gramtica es poniendo
recursividad del mismo lado que el operador en la regla sintctica donde interviene dicho
operador.
ANALIZADOR SINTCTICO
D. LA PRECEDENCIA
La precedencia de un operador indica el orden en que se aplicar respecto a los dems
operadores en caso de poder aplicar ms de uno. Es decir, si en una regla podemos aplicar ms
de un operador, comenzaremos aplicando el de ms precedencia y terminaremos por aplicar el
de menor precedencia. La manera de reflejar la precedencia en una gramtica es utilizar para
cada operador una variable en la gramtica y situarla ms cerca del smbolo inicial cuanto menor
sea la precedencia.
_____________________________________________________________________________
Ejemplo: Sintaxis de expresiones
utilizando una tabla que muestre la asociatividad y procedencia de operadores se puede
construir una gramtica para expresiones aritmtica. Se empieza con los cuatro operadores
aritmtico bsico y una tabla de precedencias, mostrando los operadores en orden de
procedencia creciente, con los operadores de la misma precedencia en la misma lnea.
asociativos por la izquierda: + asociativos por la derecha: * /
SOLUCIN A LA PROCEDENCIA:
se crean dos no terminales EXPR y TERMINO para los dos niveles de precedencia, y un no
terminal adicional factor para generar unidades bsicas en las expresiones. Ponemos primero
las reglas con menor procedencia + y - y al final de mayor precedencia * y /
Las unidades bsicas de las expresiones son de momento dgitos y expresiones entre parntesis.
()
ahora, considrese los operadores binarios * y /, que tienen mayor procedencia.
"*" "/"
ANALIZADOR SINTCTICO
LA GRAMTICA PRESENTA RECURSIVIDAD:
Hay un problema con producciones recursivas por la izquierda en la que el smbolo situado ms
a la izquierda del lado derecho de la produccin es el mismo que el no terminal del lado izquierdo
de la produccin.
SOLUCIN A LA RECURSIVIDAD POR LA IZQUIERDA:
se puede eliminar una produccin recursiva por la izquierda reescribiendo la produccin
donde a y b son secuencias de terminales y no terminales que no comienzan con A como en
nuestro ejemplo
"+"
= , = " + " =
se remplaza A por b
"+ " TERMINO
EL RESULTADO FINAL:
" + "" "
" " "/"
()
ANALIZADOR SINTCTICO
Los programas JavaCC se suelen almacenar en ficheros con extensin .jj
Al aplicar el comando javacc Ejemplo.jj produce ficheros de salida relacionados con el analizador
sintctico:
Token.java: clase que implementa el objeto a travs del cual se comunican el analizador
lxico y el sintctico.
AREA DE FUNCIONES BNF: Como ya se ha comentado, JavaCC genera un analizador
sintctico descendente implementado a base de funciones recursivas, de manera que cada
no terminal de nuestra gramtica ser convertido una funcin diferente, cuya
implementacin ser generado por javaCC. Esta tiene la siguiente estructura:
1 (1 ):
{ 1 }
{ 1 }
2 (2 ):
{ 2 }
{ 2 }
Dado que cada no terminal se convertir en una funcin en Java, el desarrollador no slo
debe indicar su nombre, sino la cabecera completa de dicha funcin. Este hecho es de
fundamental importancia puesto que:
JavaCC permite el intercambio de atributos entre reglas BNF mediante el paso de
parmetros y la obtencin de resultados en el momento de hacer uso de un no terminal (o
lo que es lo mismo invocar a la funcin que lo implementa) lo que equivale,
respectivamente, a enviar atributos hacia abajo y hacia arriba en el rbol sintctico.
6.
REFERENCIAS
ANALIZADOR SINTCTICO