Post on 21-Jan-2016
description
Compiladores
Unidad 3. Análisis Sintáctico
Contenido
Funcionalidad del analizador sintáctico. Gramáticas libres de contexto. Árboles de derivación. Especificación sintáctica de un lenguaje. Análisis sintáctico descendente. Análisis sintáctico ascendente. Generadores de analizadores sintácticos.
YACC
Funcionalidad del analizador sintáctico
La tarea del analizador sintáctico es determinar la estructura sintáctica de un programa a partir de los tokens producidos por el analizador léxico y, ya sea de manera explícita o implícita, construir un árbol de análisis gramatical o árbol sintáctico que represente esta estructura.
Funcionalidad del analizador sintáctico … (2)
La secuencia de tokens ocurre durante la sucesión de llamadas a un procedimiento del analizador léxico (pj: yylex();).
En un compilador de múltiples pasadas se hace necesario generar un árbol sintáctico para transferir y completar información entre las distintas fases.
En un compilador de una sola pasada el analizador sintáctico incorpora todas las fases del compilador y por tanto puede no ser necesario un árbol sintáctico de forma explicita.
Gramáticas libres de contexto
Todo lenguaje de programación tiene reglas que prescriben la estructura sintáctica de programas bien formados.
La estructura sintáctica se puede describir mediante gramáticas libres de contexto o notación BNF.
Así que una gramática libre de contexto puede verse como una especificación para la estructura sintáctica de un lenguaje de programación. Dicha especificación es muy similar a la especificación de
la estructura léxica del lenguaje, solo que ahora se tienen reglas recursivas.
Gramáticas libres de contexto … (2)
Una gramática libre de contexto se compone de terminales, no terminales, un símbolo inicial y producciones: Los terminales son símbolos básicos para formar secuencias.
“componente léxico” es un sinónimo de “terminal”. Los no terminales son variables sintácticas que denotan
conjuntos de secuencias. Imponen una estructura jerárquica útil para el análisis y la traducción.
El símbolo inicial esta determinado por un único no terminal. Las producciones especifican cómo se pueden combinar los
terminales y no terminales para formar secuencias.
exp → exp op exp | ( exp ) | numero
No terminales Terminales
MetasímbolosProducción
Gramáticas libres de contexto … (3) Los metasímbolos a emplear de aquí en adelante son los de uso
común, sin embargo se pueden encontrar otras representaciones
exp → exp op exp | ( exp ) | numero op → + | - | * | /
En este ejemplo los no terminales estánen cursivas, los terminales en negritas,los metasímbolos en texto normal y lasproducciones de definen por →
Otras posibles representaciones del ejemplo anterior son:
<exp> ::= <exp> <op> <exp> | ( <exp> ) | NUMERO <op> ::= + | - | * | /
exp : exp op exp | ‘(’ exp ‘)’ | NUMERO ;
op : ‘+’| ‘-’ | ‘*’ | ‘/’ ;
exp → exp op exp exp → ( exp ) exp → numero op → + op → - op → * op → /
Gramáticas libres de contexto … (4) Algunas convenciones de notación sobre gramáticas libres de contexto
Son terminales: Las primeras letras minúsculas del alfabeto (a, b, c) Los símbolos de operador (+, -, etc.) Los símbolos de puntuación (;, (, ), etc.) Los dígitos (0…9) Cadenas en negritas (id, while, etc.)
Son símbolos no terminales Las primeras letras del alfabeto (A, B, C) La letra S, que cuando aparece se tomará como el símbolo inicial. Los nombres en cursivas y minúsculas (exp, op)
Las últimas letras mayúsculas del alfabeto como X, Y, Z, representan símbolos gramaticales, es decir, terminales y no terminales
Las letras griegas minúsculas, , , , representan cadenas de símbolos gramaticales. Por tanto A → señala que existe un no terminal A a la izquierda y una cadena de símbolos gramaticales a la derecha.
Si A → 1, A → 2, … A → k, son todas producciones de A, entonces se puede escribir A → 1 | 2 … | k.
A menos que se diga otra cosa, el lado izquierdo de la primera producción es el símbolo inicial.
E → E A E | ( E ) | numero A → + | - | * | /
Gramáticas libres de contexto … (5)
Derivaciones y el lenguaje definido por una gramática Las reglas gramaticales libres de contexto determinan el
conjunto de secuencias sintácticamente legales de tokens para las estructuras definidas por las reglas.
(34 – 3) * 42Expresión aritmética:
Secuencia de tokens: ( numero – numero ) * numero
E E A E E A numero E * numero (E) * numero (E A E) * numero (E A numero) * numero (E - numero) * numero (numero - numero) * numero
E → E A EE → numeroA → *E → (E) E → E A EE → numeroA → -E → numero
ProduccionesDerivaciones
Gramática: E → E A E | ( E ) | numeroA → + | - | * | /
Gramáticas libres de contexto … (6) Se dice que A si A es una producción y y son
secuencias arbitrarias de símbolos gramaticales. Uso del símbolo
significa deriva en un paso * significa deriva en cero o más pasos + significa deriva en uno o más pasos
Dada una gramática G con símbolo inicial S, se puede utilizar la relación + para definir L(G), el lenguaje generado por G. Las cadenas de L(G) pueden contener sólo símbolos de
terminales de G. Se dice que una cadena de terminales w está en L(G) si, y sólo
si, S + w. A la cadena w se le llama frase de G. En el ejemplo anterior (34 – 3) * 42 es una frase ya que existe una
derivación a partir de la gramática dada.
Gramáticas libres de contexto … (7)
Elección del no terminal a sustituir En cada derivación se debe elegir cuál no terminal sustituir
y que regla de la gramática emplear. Algunos analizadores sintácticos eligen el no terminal más
a la izquierda, esto se conoce como derivación por la izquierda
E E A E (E) A E (E A E) A E (numero A E) A E (numero - E) A E (numero - numero) A E (numero - numero) * E (numero - numero) * numero
E → E A EE → (E)E → E A EE → numeroA → -E → numeroA → *E → numero
ProduccionesDerivaciones
Árboles de derivación
Un árbol de análisis gramatical correspondiente a una derivación es un árbol etiquetado Los nodos interiores están etiquetados por no terminales Los nodos hoja están etiquetados por terminales Los nodos hijos de cada nodo interno representan el
remplazo del no terminal asociado en un paso de la derivación
E
E A E
numero + numero
Árbol de derivación
E E A E numero A E numero + E numero + numero
Derivación
(1)
(2)
(3)
(4)
(1)
(2) (3) (4)
Árboles de derivación … (2)
Un árbol de análisis gramatical se puede considerar como una representación gráfica de una derivación que no muestra la elección relativa al orden de sustitución. Al final de la construcción del árbol las hojas se leen de
izquierda a derecha para formar una frase del lenguaje, esta frase también es conocida como el producto frontera del árbol.
E
E A E
numero + numero
Árbol de derivación
E E A E numero A E numero + E numero + numero
Derivación por la izquierda
(1)
(2)
(3)
(4)
(1)
(2) (3) (4)E E A E E A numero E + numero numero + numero
Derivación por la derecha
(1)
(2)
(3)
(4)
(1)
(2)(3)(4)
Árboles de derivación … (3)
Ambigüedad Se dice que una gramática que produce más de un árbol de
derivación para alguna frase es ambigua. Para algunos tipos de analizadores es preferible que la
gramática no sea ambigua ya que necesitan un árbol exclusivo por frase.
Algunos analizadores proporcionan métodos para admitir gramáticas ambiguas pero con especificaciones adicionales que permiten la generación de un único árbol por frase.
E → E A E | ( E ) | numA → + | - | * | /
Frase:num + num * num
Gramática:E
E
A
num +
num
E
E
E
A
* num
Árbol (deriv. der)E
E
A
num*
num
E
E
E
A
+ num
Árbol (deriv. Izq.)
Especificación sintáctica de un lenguaje La descripción de una especificación sintáctica
correspondiente a un lenguaje de programación por lo general se hace mediante una gramática libre de contexto.
Las gramáticas ofrecen ventajas significativas: Se tiene una especificación sintáctica precisa y fácil de
entender. Algunas gramáticas permiten la construcción automática
de un analizador sintáctico eficiente. Un diseño adecuado imparte una estructura útil para
traducir de lenguaje fuente a objeto y detectar errores. Permiten la adaptación a la evolución propia del lenguaje a
analizar.
Especificación sintáctica de un lenguaje … (2)
Generalmente una especificación debe estar libre de ambigüedad. Esto se logra reescribiendo la gramática.
Ejemplo:
prop if expr then prop | if expr then prop else prop | otra
If E1 then if E2 then S1 else S2
Gramática ambigua:
Frase:
prop prop_emparejada | prop_no_emparejada
prop_emparejada if expr then prop_emparejada else prop_emparejada | otra
Prop_no_emparejada if expr then prop | if expr then prop_emparejada else prop_emparejada
Gramática equivalente no ambigua:
Especificación sintáctica de un lenguaje … (3) Especificación de gramáticas recursivas
Una gramática recursiva por la derecha corresponde a la siguiente regla genérica: A A |
Una gramática recursiva por la izquierda corresponde a la siguiente regla genérica: A A |
Algunas veces es conveniente transformar una gramática recursiva por la izquierda en una recursiva por la derecha equivalente, para esto se aplican las siguientes sustituciones: A A’ A’ A’ |
Ejemplo: E E + T | TT T * F | FF (E) | id
E TE’E’ + TE’ | T FT’T’ * F T | F (E) | id
Especificación sintáctica de un lenguaje … (4)
Especificación de gramáticas factorizadas por la izquierda La idea básica es que cuando no está claro cual de dos
producciones alternativas elegir para ampliar un no terminal A, se pueden escribir las producciones de A para retrasar la decisión hasta haber visto lo suficiente de la entrada para elegir la alternativa correcta.
En general, si A→1 | 2 y la entrada inicia con un a cadena no vacía derivada de , no se sabe si expandir 1 o 2. Es posible retrazar la decisión expandiendo A en A’, entonces después de analizar se puede expandir A’ en 1 o 2.
Es decir: A→1 | 2
Se convierte en: A→A’ A’→1 | 2
Análisis sintáctico descendente Construye el árbol a partir del nodo raíz, llegando a
los nodos hoja en un recorrido preorden en profundidad.
Parten del axioma inicial, y van efectuando derivaciones por la izquierda hasta obtener la secuencia de derivaciones que reconocen la frase de entrada.
Algunos tipos de análisis descendente Por descenso recursivo Predictivos Predictivos no recursivos LL(1)
Análisis sintáctico descendente … (2) El análisis sintáctico por descenso recursivo pretende:
Encontrar una derivación por la izquierda para una cadena de entrada.
Construir un árbol de análisis sintáctico para la entrada comenzando desde la raíz y creando los nodos del árbol en orden previo.
Este tipo de análisis requiere gramáticas no recursivas por la izquierda.
Ejemplo:
Gramática:
S→cAdA→ab | a
Frase:w = cad
S
c A d
Se crea el árbol a partir de S, se empata con la hoja situada más ala izquierda etiquetada con c, elprimer símbolo de w
S
c A d
a bSe avanza al siguiente símbolo dela frase (a) y se considera la siguientehoja etiquetada con A. Expandiendo laprimera alternativa de A. La primera hoja de A empata pero la segunda no.Se señala un fallo y se verifica si existeotra alternativa de A que no se hayaprobado.
S
c A d
aAl regresar a A, se debe restablecerel apuntador de la entrada. Despuésse empata con la única hoja de A a,y también se empata con la hoja d.Como ya se ha producido un árbol parala frase w se anuncia el éxito.
Análisis sintáctico descendente … (3)
Analizadores sintácticos predictivos Es una variante del método de análisis sintáctico
por descenso recursivo. Se emplean cuando se tiene una gramática sin
recursividad por la izquierda y factorizada por la izquierda, cumpliendo con estas dos condiciones no se necesita el retroceso.
La alternativa apropiada de la gramática se detecta con ver prácticamente el primer símbolo al que da lugar.
Análisis sintáctico descendente … (4) Análisis sintáctico predictivo no recursivo
Se puede eliminar la recursividad explicita manteniendo una pila.
Se busca la producción que debe aplicarse en una tabla de análisis sintáctico.
Modelo:
Programa para análisis sintáctico
predictivo
Tabla de análisis sintáctico M
a + b $
X
Y
Z
$
PILA
ENTRADA
SALIDA
M[X,a]
Alfabeto de pilaformado por terminalesy no terminales junto conel símbolo de $ delimitadorde la cadena de entrada
Alfabeto de entradaformado por los símbolosterminales
La tabla de análisis en unarreglo de la forma M[X,a]donde X representa un símbolono terminal y a representa unsímbolo terminal
Análisis sintáctico descendente … (5)
Análisis sintáctico predictivo no recursivo … Funcionamiento:
Al principio la pila contiene el símbolo inicial de la gramática encima de $.
Se tiene en cuenta X, el símbolo en el tope de la pila, y a, el símbolo en curso de la entrada, entonces; Si X = a = $, el análisis se detiene exitosamente. Si X = a $, el analizador saca X de la pila y mueve el apuntador
de la entrada al siguiente símbolo. Si X e un símbolo no terminal, entonces:
Si M[X, a] tiene una regla X→UVW, entonces saca X del tope e introduce WVU en la pila (U queda en el tope)
Si M[X, a] = error, se llama la rutina de recuperación de error
Análisis sintáctico descendente … (6) Análisis sintáctico predictivo no recursivo …
Ejemplo:
E → TE’ E’ → +TE’ | T → FT’ T’ → *FT’ | F → (E) | id
Gramática:
PILA ENTRADA SALIDA$E id + id * id$$E'T id + id * id$ E → TE'$E'T'F id + id * id$ T → FT'
$E'T' id id + id * id$ F → id$E'T' + id * id$$E' + id * id$ T' →
$E'T + + id * id$ E' → +TE'$E'T id * id$$E'T'F id * id$ T → FT'
$E'T' id id * id$ F → id$E'T' * id$$E'T'F * * id$ T' → *FT'$E'T'F id$$E'T' id id$ F → id$E'T' $$E' $ T' →
$ $ E' →
No Terminal id + * ( ) $E E → TE' E → TE'E' E' → +TE' E' → E' → T T → FT' T → FT'T' T' → T' → *FT' T' → T' → F F → id F → (E )
Símbolo de entrada
Tabla M:
Algoritmo Movimientos dada la entradaid + id * id
Análisis sintáctico descendente … (7) Análisis sintáctico predictivo no recursivo …
Se facilita la construcción de un analizador sintáctico predictivo con dos funciones asociadas a la gramática G: PRIMERO()
Conjunto de terminales que inician cadenas derivadas de Si * , entonces también está en primero.
SIGUIENTE (A) Conjunto de terminales a que pueden aparecer inmediatamente a la derecha de A. S * Aa para algún y . Entre A y a pudieron existir derivaciones que terminaron en . Es decir si S * ABCa, y B * y C * , entonces a esta
en SIGUIENTE (A) $ esta situado en SIGUIENTE (A)
Para calcular todos los PRIMERO (X)1. Si X es terminal, entonces PRIMERO (X) es {X}2. Si X → , entonces añádase a PRIMERO (X)3. Si X es no terminal y X → Y1, Y2, .. Yk, entonces poner a en PRIMERO (X) si, para alguna i, a está en PRIMERO (Yi) y
Y1, Y2, .. Yi-1 * . Para calcular SIGUIENTE (A)
1. Poner $ en SIGUIENTE (S), donde S es el símbolo inicial2. Si hay una producción A → B, entonces todo lo que esté en PRIMERO () excepto se pone en SIGUIENTE (B)3. Si hay una producción A → B o una producción A → B, donde PRIMERO () contenga , entonces todo lo que esté
en SIGUIENTE (A) se pone en SIGUIENTE (B) Ejemplo:
E → TE’ E’ → +TE’ | T → FT’ T’ → *FT’ | F → (E) | id
PRIMERO(): SIGUIENTE (A):
PRIMERO (E) = PRIMERO (T) = PRIMERO (F) = {(, id}PRIMERO (E’) = {+, }PRIMERO (T’) = {*, }
SIGUIENTE (E) = SIGUIENTE (E’) = P {$, )}SIGUIENTE (T) = SIGUIENTE (T’) = {+, $, )}SIGUIENTE (F) = {*, +, $, )}
Análisis sintáctico descendente … (8) Análisis sintáctico predictivo no recursivo …
Construcción de tablas de análisis sintáctico1. Para cada producción A → de la gramática, dense los pasos 2 y 32. Para cada terminal a de PRIMERO (), añádase A → a M[A, a]3. Si está en PRIMERO (), añádase A → a M[A, b] para cada terminal b de SIGUIENTE (A). Si
está en SIGUIENTE (A), añádase A → a M [A, $]4. Hacer cada entrada no definida de M sea error.
No Terminal id + * ( ) $E E → TE' E → TE'E' E' → +TE' E' → E' → T T → FT' T → FT'T' T' → T' → *FT' T' → T' → F F → id F → (E )
Símbolo de entrada
E → TE’ E’ → +TE’ | T → FT’ T’ → *FT’ | F → (E) | id
Gramática: PRIMERO(): SIGUIENTE (A):
PRIMERO (E) = PRIMERO (T) = PRIMERO (F) = {(, id}PRIMERO (E’) = {+, }PRIMERO (T’) = {*, }
SIGUIENTE (E) = SIGUIENTE (E’) = P {), $}SIGUIENTE (T) = SIGUIENTE (T’) = {+, ), $}SIGUIENTE (F) = {+, *, ), $}
P → iEtPP’ | a P’ → eP | E → b
Gramática:
Análisis sintáctico descendente … (9) Gramáticas LL(1)
La entrada se lee de izquierda a derecha [LL(1)], las derivaciones se realizan por la izquierda [LL(1)] y se necesita conocer un token de la entrada por anticipado [LL(1)].
Propiedades: Ninguna gramática ambigua o recursiva por la izquierda puede ser LL(1) G es LL(1), si y sólo si, cuando A → | sean dos producciones distintas de
G cumplen con: Para ningún terminal a tanto como derivan a la vez cadenas que comiencen con
a. A lo sumo una de y pude derivar en cadena vacía. Si * , no deriva ninguna cadena que comience con un terminal en SIGUIENTE
(A). Cuando se tienen dos entradas en una celda de la tabla del análisis
sintáctico la gramática es ambigua, entonces se puede intentar: Eliminar toda la recursión por la izquierda, y Factorizar por la izquierda siempre que sea posible Sin embargo puede darse el caso de que ni así se elimina la ambigüedad
La mayor dificultad del análisis sintáctico predictivo consiste en escribir una gramática para el lenguaje fuente tal que el analizador se pueda construir a partir de dicha gramática.
Análisis sintáctico ascendente Este tipo de análisis también es conocido como análisis
sintáctico por desplazamiento y reducción Intenta construir un árbol de análisis sintáctico para una frase de
entrada que comienza por las hojas y avanza hacia la raíz. Este proceso se puede considerar como “reducir” la frase w al
símbolo inicial de la gramática. En cada paso de reducción se sustituye una subcadena
determinada que concuerde con el lado derecho de una producción por el símbolo izquierdo de dicha producción.
Si en cada caso se elige correctamente la subcadena, se traza una derivación por la derecha en sentido inverso.
Ejemplo:
S → aABeA → Abc | bB → d
abbcde
Gramática Frase: Reducción:abbcdeaAbcdeaAdeaABeS
Análisis sintáctico ascendente … (2) La construcción del árbol sintáctico de abajo hacia arriba permite:
Disminuir el número de reglas mal aplicadas respecto a los analizadores descendentes con retroceso.
Ampliar el número de gramáticas susceptibles de ser analizadas respecto a las gramáticas LL(1)
Tomando en cuenta que la lectura de la frase a reconocer es de izquierda a derecha, esta se compone de dos partes: representa un segmento de la frase de entrada por consumir
T*
Coincidirá siempre con algún segmento de la parte derecha de la frase de entrada Al principio coincide con la frase completa (incluyendo el EOF)
representa un segmento de la frase de entrada consumido (N T)*
Coincidirá siempre con el resto de la frase de entrada a la cual ya se le aplicó una regla de reducción en sentido inverso.
Ejemplo:Gramática:
(1)E → T + E(2) | T(3)T → F * T(4) | F(5)F → id(6) | (E)
Frase:
id + id
id + id
1) Al principio
2) Consumiendo el 1er token
id + id
3) Aplicando las reglas (5) y (4) hacia atrás
id + id
F
T
4) aplicando la regla (2) hacia atrás y consumiendo el 2do token
id + id
F
T
E
Análisis sintáctico ascendente … (3) Operaciones en un analizador ascendente
Aceptar Se acepta la frase EOF
Rechazar Se rechaza cuando la entrada no es válida
Reducir Aplica una regla de producción hacia atrás a algunos elementos posicionados a
la derecha de Si se tiene: [X1 X2 … Xp Xp+1 … Xm] - [am+1 … an] Y existe una regla: Ak → Xp+1 … Xm , entonces: Una reducción quedaría: [X1 X2 … Xp Ak] - [am+1 … an] Por otro lado para una regla de tipo: Ak → Se obtiene [X1 X2 … Xp Xp+1 … Xm Ak] - [am+1 … an]
Desplazar Consume (quita) el terminal más a la izquierda de y ponerlo a la derecha de .
Si se tiene [X1 X2 … Xp Xp+1 … Xm] - [am+1 … an] Aplicando un desplazamiento queda: [X1 X2 … Xp Xp+1 … Xm am+1] - [am+2 … an]
En resumen: Mediante desplazamientos y reducciones se debe aceptar o rechazar la frase
de entrada.
Análisis sintáctico ascendente … (4) Los diferentes tipos de analizadores sintácticos ascendentes se
distinguen unos de otros en base a la lógica de cuando aplicar cada una de las cuatro operaciones del analizador.
Los tipos de analizadores se pueden ver en función de la gramática que son capaces de procesar, estas son: SLR(k)
Simple Left-to-right Rightmost derivation LALR(k)
Look Ahead Left-to-right Rightmost derivation LR(k)
Left-to-right Rightmost derivation Dichas gramáticas están incluidas unas en otras de la siguiente
forma: SLR(K) LALR(K) LR(K)
Análisis sintáctico ascendente … (5)
Análisis ascendente de gramáticas LR(1) Es capaz de reconocer prácticamente cualquier lenguaje
de programación que pueda ser generado por una gramática libre de contexto.
Puede localizar un error sintáctico casi en el mismo instante en que se produce.
Permite emitir mensajes de error indicando con cierta precisión la fuente del error.
Tiene el inconveniente de hacer demasiado extensa la implementación “manual” del analizador, afortunadamente existen generadores automáticos de analizadores sintácticos LR, en particular LALR(1) el YACC.
Análisis sintáctico ascendente … (6)
Estructura general de un analizador LR
Xi es un símbolode la gramática
si son los estadosdel autómata asociadoa la gramáticasi E
Consultando el estado en la cabeza dela pila y el siguiente token en la entradase decide que reducción efectuar o si esnecesario desplazar y el siguiente estado.
Análisis sintáctico ascendente … (7)
Funcionamiento del analizador LR Suponiendo que en un momento dado el estado que hay en la
cima de la pila es sm y el token actual es ai se deben aplicar reiteradamente los siguientes pasos hasta aceptar o rechazar la frase: Consultar la entrada (sm, ai) en la tabla ACCION
El contenido de la casilla puede ser: Aceptar, Rechazar, Reducir por A , Desplazar
Si se acepta o se rechaza se da por finalizado el análisis Si se desplaza se mete ai a la pila Si se reduce, entonces la cima de la pila coincide con el consecuente y
se sustituye por A. Una vez hecho el paso anterior en la cima de la pila hay un símbolo,
lo que dará una entrada en la tabla de GOTO. El contenido de dicha tabla se coloca en la cima de la pila.
Análisis sintáctico ascendente … (8)
Por razones de espacio las tablas de ACCION y GOTO suelen tratarse como una sola dividida en dos partes: Unas columnas comunes a ACCION y GOTO
Contienen D-i: Desplazar y pasar al estado i R j: Reducir por la regla de producción número j. En este caso
debe aplicarse a continuación la tabla GOTO. Aceptar Cacillas vacías rechazan la gramática
Otras columnas solo a GOTO Contienen números de estado a los que se transita Casillas vacías representan un error
Análisis sintáctico ascendente … (9)
Ejemplo:
(1)E → T + E(2) | T(3)T → F * T(4) | F(5)F → (E)(6) | id
Análisis sintáctico ascendente … (10)
Algunas consideraciones sobre el análisis LR Recursividad
Para que la pila se mantenga de un tamaño razonable alternando entre desplazamientos y reducciones es aconsejable utilizar gramáticas recursivas por la izquierda.
Conflictos Desplazar/Reducir (shift/reduce)
Suele darse debido a gramáticas recursivas El programa no sabe si desplazar o reducir, ya que ambas
opciones aparecen en la tabla asociada a la gramática Reducir/Reducir (reduce/reduce)
Se debe a que la gramática no admite un análisis LR(1), es decir se necesita más de un token de preanálisis
Por lo regular estos errores se pueden eliminar retrasando la desición de reducción al último momento.
Generadores de analizadores sintácticos
Clasificación de los generadores de analizadores
Generadores de analizadores sintácticos … (2)
Un generador de analizadores sintácticos es un programa que convierte una especificación sintáctica de un lenguaje (en términos de una GLC) en un analizador sintáctico del lenguaje especificado.
La utilización de generadores de analizadores automáticos permite: Reducir la complejidad y el tiempo de implementación Aumentar la calidad del compilador Actualizar y corregir con mayor facilidad el compilador
Generadores de analizadores sintácticos … (3)
Proceso para construir un analizador sintáctico mediante un generador de analizadores sintácticos Describir la gramática
Cada generador tiene sus propias reglas para la especificación Procesar la gramática con el generador
El resultado es el código fuente del analizador (parser) en algún lenguaje en particular (típicamente en C)
Compilar el código fuente del analizador Puede ser necesario hacer este paso en conjunto con la compilación
de las otras fases
GramáticaGenerador
de parser
Código fuentedel parser
Compilador(C, C++, etc.)
Procesadorde
Lenguaje
Código fuentedel scanner
YACC
Se trata de un generador de analizadores sintácticos Se basa en gramáticas LALR(1) Se apoya en LEX para el reconocimiento de tokens
YACC … (2)
El entorno de yacc