Você está na página 1de 14

El analizador sintctico es una de las fases

de un compilador donde se tiene por


finalidad verificar el ordenar los tokens ,
obtenidos del analizador lexicogrfico, a
partir de una gramtica de libre contexto.

ANALIZADOR
SINTCTICO

ROQUE CALDAS DOMINGUEZ

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.

Figura 1.1|rbol sintctico

Figura 1.2|rbol sintctico

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.

2. FUNCIONES DEL ANALIZADOR SINTCTICO


La funcin principal del analizador sintctico es determinar si una cadena de componentes
lxicos puede ser generada por una gramtica.
Controla el flujo de tokens reconocidos por parte del analizador lxico y comprueba si la cadena
pude ser generada por la gramtica del lenguaje fuente.
Informa de la naturaleza de los errores sintcticos que encuentra e intenta recuperarse de ellos
para continuar la compilacin.

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.

Figura 3.1|Entradas y salidas de las dos primeras fases de la etapa de anlisis.

Las gramticas ofrecen ventajas significativas:

Una gramtica da una especificacin sintctica precisa y fcil de entender de un lenguaje


de programacin.

ANALIZADOR SINTCTICO

A partir de algunas clases de gramticas se puede construir automticamente un


analizador sintctico eficiente que determine si un programa fuente est
sintcticamente bien formado.

El proceso de construccin del analizador sintctico puede revelar ambigedades


sintcticas y otras construcciones difciles de analizar que de otro modo podran pasar
sin detectar en la fase inicial de diseo de un lenguaje y de su compilador.

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:

Cabeza: no terminales (lado izquierdo de la produccin).

: smbolo de produccin.se lee se define como o puede tener la forma

Cuerpo: cadena de 0 o ms smbolos terminales y/o no terminales (lado derecho de


la produccin).

S= Axioma inicial. Primer elemento de la gramtica.


Las gramticas libres de contexto permiten describir la mayora de lenguajes de programacin,
de hecho, la sintaxis de la mayora de lenguajes de programacin est definida mediante
gramticas libres de contextos.
Pongamos un ejemplo de gramtica e identificaremos cada uno de los elementos. Sea la
gramtica:

E+T | T

T*F|F

id | F |(E)

E, T, F son las no terminales.


id, +, *, (,) son terminales.
Hay tres reglas de produccin
E es el axioma inicial.

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

A. DERIVACIONES UTILIZANDO UNA GRAMTICA

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.

Dependiendo de por dnde comencemos a reescribir en la pseudocadena, tendremos una


derivacin por la izquierda (si comenzamos por la izquierda) o por la derecha (si comenzamos
por la derecha). Si queremos construir una cadena de tokens que sean generadas por una
gramtica concreta, podremos hacerlo aplicando las reglas de la gramtica segn vayan
concordando con los tokens.
Por ejemplo, supongamos que tenemos la siguiente gramtica:
+ ()
Derivacin por la izquierda
+ 1 + 1 + 2 1 + 2 3
Es aquella en la que la reescritura se realiza sobre el no terminal ms a la izquierda de la
pseudocadena de partida.
Derivacin por la derecha

3 + 3 + 2 3 1 + 2 3

ANALIZADOR SINTCTICO

Es aquella en la que la reescritura se realiza sobre el no terminal ms a la derecha de la


pseudocadena de partida.
A partir de estas derivaciones se puede construir sus rboles sintcticos. Pero hay cosas en que
cada posible derivacin dar lugar a un rbol sintctico diferente. Esto significa que la gramtica
es ambigua.
Veamos un ejemplo. Supongamos que tenemos la gramtica anterior y queremos procesar estos
tokens:

1 + 2 + 3
Hay dos posibles rboles sintcticos:

Figura 3.2|Derivacin por la izquierda

Figura 3.3| Derivacin por la derecha

Por lo tanto, deduciremos que la gramtica es ambigua. Para la implementacin de esta


gramtica, es necesario esta ambigedad. El orden en que vamos creando las ramas y las hojas
no da la idea del orden en que se irn procesando las reglas. Por lo tanto, tenemos un
mecanismo secuencial de procesamiento.

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.

DIFICULTADES PARA LA CREACIN DE GRAMTICAS


A. RECURSIVIDAD

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:

Donde A es un no terminal y a y b son terminales o no terminales. Al ter minal A le llamamos t


erminal recursivo. Si no existe el trmino a, se trata de una recursividad por la izquierda y si no
existe b es una recursividad por la derecha.

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:

Gramticas con ciclos:

ANALIZADOR SINTCTICO

Gramticas con alguna regla de la forma:


.

Gramticas con unas reglas que ofrezcan caminos alternativos entre dos puntos.
Por ejemplo:

Producciones recursivas en las que las variables no recursivas de la produccin

puedan derivar a la cadena vaca.


Por ejemplo:

Smbolos no terminales que puedan derivar a la cadena vaca y a la misma cadena de


terminales, y que aparezcan juntas en la parte derecha de una regla o en alguna forma
sentencia.
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.1|rbol de anlisis sintctico para la proposicin condicional

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.
"*" "/"

de manera similar, <expr> genera listas de trminos separados


EXPR " + " " "
por lo tanto, la gramtica resultante es:

" + "" "


" " "/"
()
es posible que un analizador sintctico descendiente recursivo entre en un bucle indefinido.
> +

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:
" + "" "
" " "/"
()

5. ANALIZADOR SINTCTICO EN JAVACC


Se trata de una herramienta que facilita la construccin de analizadores lxicos y sintcticos por
el mtodo de las funciones recursivas, aunque permite una notacin relajada muy parecida a la
BNF.

Genera analizadores descendentes, permitiendo el uso de gramticas de propsito


general y la utilizacin de atributos tanto sintetizados como heredados durante la

construccin del rbol sintctico.

Las especificaciones lxicas y sintcticas se ubican en un solo archivo. De esta manera la


gramtica puede ser leda y mantenida ms fcilmente. No obstante, cuando se
introducen acciones semnticas, recomendamos el uso de ciertos comentarios para
mejorar la legibilidad.

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:

Ejemplo.java: es el analizador sintctico.

EjemploTokenManager.java: es el analizador lexicogrfico.

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

Compiladores Principios, tcnicas y herramientas. Alfred V. Aho, Ravi Sethi,


Jeffrey D. Ullman Adisson Wesley.

Compiladores Conceptos fundamentales. Teufel, Schmidt, Teufel. Adisson


Wesley Iberoamericana.

Modern compiler implementation in C. Appel. Cambridge

ANALIZADOR SINTCTICO

Teora de Autmatas y Lenguajes Formales. Dean Kelley. PrenticeHall Cambridge

Você também pode gostar