Sunteți pe pagina 1din 13

USANDO GENERADORES DE ANALIZADORES SINTCTICOS

La tarea de construir un analizador sintctico es lo suficientemente simple como para ser


automatizada. En el captulo anterior hemos descrito los aspectos de anlisis lxico de JavaCC y
SableCC. Aqu vamos a discutir los aspectos del generador de anlisis de estas herramientas. La
documentacin para JavaCC y SableCC estn disponibles a travs del sitio Web de este libro.
JavaCC es un LL (k) generador de analizadores sintcticos. Sus producciones son de la forma:
void Assignment() : {} { Identifier() "=" Expression() ";" }
Donde el lado izquierdo es de Asignacin (); el lado derecho est encerrado entre los dos ltimos
corchetes; Asignacin (), identificador (), y la expresin () son smbolos no terminales; y "=" y ";" son
smbolos terminales.


La gramtica 3.30 puede ser representada como una gramtica JavaCC como se muestra en la
gramtica 3.31. Tenga en cuenta que si hubiramos escrito para la produccin StmList () en el estilo
de gramtica 3.30 es

A continuacin, la gramtica se dej recursiva. En este caso, JavaCC dara el siguiente error:

Utilizamos las tcnicas mencionadas anteriormente para eliminar la recursividad por la izquierda y
llegar a la gramtica 3.31.
SABLECC
SableCC es un LALR (1) generador de analizadores sintcticos. Sus Producciones son de la forma:

Donde el lado izquierdo es la asignacin; el lado derecho est encerrado entre = y ;; asignacin,
identificador, y la expresin son smbolos no terminales; y assing y coma son smbolos terminales
que se definen en una parte anterior de la especificacin de sintaxis.
La gramtica 3.30 se puede representar como una gramtica en SableCC como se muestra en la
gramtica 3.32. Cuando hay ms de un alternativa SableCC Requiere un nombre para cada
alternativa. Un nombre se le da a una alternativa en la gramtica prefijando un identificador con la
alternativa entre corchetes. Adems, si el mismo smbolo gramatical aparece dos veces en la misma
alternativa de una produccin, SableCC requiere un nombre para al menos uno de los dos
elementos. Los nombres de elementos se especifican anteponiendo el elemento con un identificador
entre corchetes seguido de dos puntos.
Ese reporte de SableCC en la Gramtica 3.32 tiene un desplazamiento y reduccin de conflictos. El
conflicto puede ser examinado por la lectura del mensaje de error detallado que SableCC produce,
como se muestra en la Figura 3:33.


SableCC usa prefijos para sus producciones con una "P" mayscula y tokens con una mayscula
"T", y sustituye la primera letra con mayscula cuando hace los objetos para los tokens y
producciones. Esto es lo que se ve en la pila en el mensaje de error en la Figura 3:33. S que
tenemos las fichas en la pila para if, id, then, y en la produccin de stm que se coincide, y ahora
tenemos una sentencia else token. Es evidente que esto revela que el conflicto es causado por else.
Con el fin de resolver este conflicto tenemos que reescribir la gramtica, la eliminacin de la
ambigedad como en la gramtica 3,34.



DIRECTIVAS DE PRIORIDAD
Una gramtica no ambigua es LR (k) para cualquier k; la tabla de anlisis sintctico LR (k) de una
gramtica ambigua siempre tendr conflictos. Sin embargo, las gramticas ambiguas todava pueden
ser tiles si podemos encontrar la manera de resolver los conflictos.
Por ejemplo, Gramtica 3.5 es muy ambigua. Mediante el uso de esta gramtica para describir un
lenguaje de programacin, se pretende que sea analizada de manera que * y / unirse fuertemente a
moras + y -, y que cada operador se asocia a la izquierda. Podemos expresar esta reescribiendo la
inequvoca Gramtica 3.8
Pero podemos evitar la introduccin de los smbolos T y F y sus correspondientes reducciones
"triviales" E T y T F. En su lugar, vamos a empezar por la construccin de la (1) tabla de
anlisis sintctico LR para Gramtica 3.5, como se muestra en la Tabla 3.35. Encontramos muchos
conflictos. Por ejemplo, en el estado 13 con bsqueda hacia delante + nos encontramos con un
conflicto entre el cambio en 8 y estbamos de nuevo por la regla 3. Dos de los artculos estamos en
el estado 13




En esto fue la parte superior de la pila es E * E. Shifting conducir a una pila E * E + y E *
Finalmente E + E con una reduccin de E + E para E. Reduccin ahora dar lugar a la pila E
y luego el + se desplazar. Los rboles de anlisis se obtiene desplazando y reduciendo


* Si queremos unir ms apretado que +, debemos veterano en lugar de turno. As que llenamos la
entrada (13 +) en la tabla con r3 y descartamos la accin s8. Por el contrario, en el estado de 9 de
preanlisis *, debemos cambiar en lugar de reducir, por lo que la resolucin del conflicto mediante la
cumplimentacin de la entrada (9, *) con s12. Las casas eran de 9 + preanlisis es

Desplazamiento har que el operador asociativo por la derecha; reduccin har que sea dejado
asociativo. Desde que salimos de asociatividad que desee, rellene w (9 +) con r5.
Considere la posibilidad de la expresin a - b - c. En la mayora de los lenguajes de programacin,
esto se asocia a la izquierda, como si estuviese escrita (a - b) - c. Pero se supone que debemos
creer que esta expresin es intrnsecamente confuso, y queremos forzar al programador para poner
en explcita parntesis, (a - b) - c o - (b - c). Se dice entonces que el operador menos es no
asociativo, y nos gustara llenar el (11 -) entrada con una entrada de error.


El resultado de todas estas decisiones es una tabla de anlisis sintctico con todos los conflictos
resueltos (Cuadro 3:36).
Tiene directivas de precedencia yacc establecer la resolucin de esta clase de conflictos por
desplazamiento y reduccin. (Desafortunadamente, SableCC no tiene directivas de precedencia.)
Una serie de declaraciones: como
precedence nonassoc EQ, NEQ;
precedence left PLUS, MINUS;
precedence left TIMES, DIV;
precedence right EXP;

Indica que las teclas + y - se asociativo por la izquierda y se unen igualmente bien; que * y / quedan
asociativo y se unen fuertemente a + moras; Eso es asociativo por la derecha y se une ms
fuertemente; y Que = y? = son no asociativo, moras y se unen dbilmente a +.
Al examinar una por desplazamiento y reduccin de conflictos: como


existe la opcin de cambiar una ficha y la reduccin por una regla. En caso de que la regla o el token
se otorgue una mayor prioridad? . Las declaraciones de precedencia (de precedencia izquierda, etc)
Dar a las prioridades a las fichas; la prioridad de una regla est dada por la ltima ficha que ocurre
en el lado derecho de la regla. Por lo tanto la eleccin aqu es entre una regla y una ficha con
prioridad con prioridad * +; Tiene la regla de mayor prioridad, por lo que el conflicto se resuelve a
favor de la reduccin.

Cuando la regla y tokens tienen la misma prioridad, entonces favores de precedencia que reducen a
la izquierda, derecha, favorece el cambio y nonassoc produce una accin de error.

En lugar de utilizar el valor predeterminado "regla tiene precedencia de su ltima ficha," podemos
asignar una prioridad a una regla especfica usando la directiva prec%. Esto es comnmente
utilizado para resolver el problema "menos unario". En la mayora de los lenguajes de programacin
para menos unario une ms apretado que cualquier operador binario, por lo -6 * 8 se analiza como (-
6) * 8, no - (6 * 8). Gramtica 03:37 muestra un ejemplo.

El UMINUS smbolo nunca es devuelto por el analizador lxico; es slo un marcador de posicin en
la cadena de declaraciones de precedencia. La directiva da la regla UMINUS% anterior exp :: = exp
MINUS la ms alta prioridad, por lo que la reduccin por esta regla tiene prioridad sobre todos los
operadores de desplazamiento, incluso en el signo menos.

Reglas de precedencia son tiles en la resolucin de los conflictos, pero no se debe abusar. Si tiene
problemas para explicar el efecto de un uso inteligente de las reglas de prioridad, tal vez en su lugar
debe reescribir la gramtica para ser inequvoco.
SEMNTICA VERSUS SINTAXIS
Considere la posibilidad de un lenguaje de programacin con expresiones aritmticas: como x + y, y
expresiones booleanas: tal como x + y = z or a & (b = c). Los operadores aritmticos enlazan ms
estricto que los operadores booleanos; hay variables aritmticas y variables booleanas; y una
expresin booleana no se puede aadir a una expresin aritmtica. Gramtica 3.38 da una sintaxis
de este lenguaje. La gramtica tiene un conflicto de reduccin-reduccin. Cmo debemos reescribir
la gramtica para eliminar este conflicto?

Es ese el problema aqu Cuando el intrprete ve un identificador en: por ejemplo, no tiene forma de
saber si se trata de una variable de clculo o una variable boolean - se ven sintcticamente idnticos.
La solucin es aplazar este anlisis hasta la fase de "semntica" del compilador; Eso no es un
problema se puede manejar de forma natural con las gramticas libres de contexto. A moras
gramtica apropiada es

Ahora la expresin a + b es sintcticamente legal y 5, y una fase posterior del compilador tendr que
rechazarlo e imprimir un mensaje de error semntico.
RECUPERACIN DE ERRORES
LR (k) tablas de anlisis sintctico Contienen cambio, reducir, aceptar, y las acciones de error. En la
pgina 58 hemos afirmado que cuando un analizador LR se encuentra con una accin de error que
se detenga el anlisis y el fracaso informes. Este comportamiento sera cruel con el programador,
que le gustara tener todos los errores indicados en su programa, no slo el primer error.

RECUPERACIN DE ERRORES DE USAR EL SMBOLO
Mecanismos de recuperacin de errores locales trabajan mediante el ajuste de la pila de anlisis
sintctico y la entrada en el punto donde se detect el error en una forma que permita el anlisis para
reanudar. Uno de los mecanismos de recuperacin local - que se encuentra en muchas versiones del
generador de analizadores sintcticos YACC - utiliza un error de smbolo especial para controlar el
proceso de recuperacin. Dondequiera que el smbolo de error especial aparece en una regla
gramatical, una secuencia de tokens de entrada errneas puede ser igualada.
Por ejemplo, en un Yacc las producciones gramaticales: como puede ser que tengamos

Informalmente, se puede especificar que si se encuentra un error de sintaxis en el medio de una
expresin, el analizador debe saltar al siguiente punto y coma o parntesis derecho (Estos se llaman
sincroniza tokens) y reanudar el anlisis. Hacemos esto mediante la adicin de las producciones de
recuperacin de errores: por ejemplo,

Qu hace el generador de analizador con el smbolo de error? En la generacin de analizadores
sintcticos, error es considerado un smbolo terminal, y acciones de transferencia se introducen en la
tabla de anlisis sintctico para ella como si se tratara de un smbolo ordinario.
Cuando el analizador LR alcanza un estado de error, toma las acciones siguientes:

1. Pop la pila (si es necesario) hasta que se alcanza un estado en el que la accin para el token error
es cambio.
2. Cambie el token error.
3. Deseche smbolos de entrada (si es necesario) hasta que se alcanz una bsqueda hacia delante
que lo tiene una accin nonerror en el estado actual.
4. Reanudar el anlisis normal.

En las dos producciones de error ilustrados anteriormente, hemos tenido el cuidado de seguir el
smbolo con un smbolo de sincronizacin de error correspondiente - en este caso, un parntesis o
punto y coma bien. Por lo tanto, la "accin nonerror" tomada en el paso 3 siempre cambiar. Si en
cambio se utiliz el error exp produccin, la "accin nonerror" estara de vuelta, y (en una SLR o
LALR parser) Que es posible la (errnea) smbolo de preanlisis originales causara otro error
despus de la accin de veterano, sin tener avanzado la entrada. Por lo tanto, las reglas
gramaticales que contienen errores no Seguido por una ficha deben ser apenada Slo cuando no
hay una buena alternativa.

Precaucin

Uno puede adjuntar acciones semnticas a las reglas gramaticales Yacc; Cada vez que se reduce
una regla, se ejecuta su accin semntica. Captulo 4 explica el uso de las acciones semnticas.
Popping estados de la pila puede llevar a acciones semnticas aparentemente "imposibles",
especialmente si las acciones Contener los efectos secundarios. Considere este fragmento de
gramtica:

"Obviamente," es cierto que cada vez que se alcanza un punto y coma, el valor de un nido es cero,
puesto que se incrementa y disminuye de manera equilibrada de acuerdo a la gramtica funcional de
las expresiones. Pero si se encuentra un error de sintaxis despus de algunos parntesis de
izquierda no se han analizado, a continuacin, los estados se extraen de la pila sin "Finalizacin", lo
que lleva a un valor distinto de cero de un nido. La mejor solucin a este problema es tener de
efectos secundarios acciones semnticas gratuitas que construye rboles de sintaxis abstracta, tal
como se describe en el Captulo 4.
Desafortunadamente, JavaCC ni apoya ni SableCC el mtodo de recuperacin de errores smbolo de
error, ni el tipo de reparacin de errores global se describe a continuacin.
REPARACIN ERROR GLOBAL
Reparacin de errores Global encuentra el conjunto ms pequeo de las inserciones y deleciones
que convertira la cadena de origen en una cadena sintcticamente correcta, incluso si las
inserciones y eliminaciones no estn en un punto en el que una o LL LR parser primero informar de
un error.

Reparacin de errores Burke-Fisher. Vamos a describir una forma limitada pero til de la reparacin
de errores global, que intenta todo lo posible la insercin nico token, eliminacin o sustitucin en
cada punto Eso no antes de K se produce fichas antes del punto en el analizador de informar del
error. As, con K = 15, si el motor de anlisis se queda atascado en la ficha nmero 100 de la
entrada, entonces se intentar todo lo posible la reparacin entre el 85o y 100o tokens.
La correccin que permite que el analizador para analizar ms lejos ms all del error reportado
original se toma como la mejor reparacin del error. Por lo tanto, si una sola sustitucin de tokens de
var para el tipo en el token 98a Permite que el motor de anlisis de proceder ms all de la seal
104a sin atorarse, esta reparacin es un xito. Generalmente, si el analizador para la reparacin
lleva R = 4 tokens all donde originalmente se atasc, esto es "lo suficientemente bueno."

La ventaja de esta tcnica es que el LL (k) o LR (k) (o LALR, etc). Gramtica no se modifica en
absoluto (no hay producciones de error), ni las tablas de anlisis se modifican. Slo el motor de
anlisis, que interpreta las tablas de anlisis sintctico, se modifica.

El motor de anlisis debe ser capaz de copia de seguridad de los tokens K y reanlisis. Para ello, es
necesario recordar lo que la pila de anlisis sintctico que pareca tokens K en agosto Por lo tanto, el
algoritmo mantiene dos pilas de anlisis sintctico: la pila actual y la antigua pila. Una cola de tokens
K se mantiene; ya que cada nuevo token se desplaza, se inserta en la pila actual y tambin poner en
la cola de la cola; al mismo tiempo, se retira la cabeza de la cola y se movi hacia la vieja pila. Con
cada cambio en la edad o la corriente de pila, el veterano apropiada tambin se llevan a cabo las
acciones. Figura 3:39 Ilustra las dos pilas y colas.

Ahora supongamos que se detecta un error de sintaxis en el smbolo actual. Para cada posible
insercin, eliminacin o sustitucin de una ficha en cualquier posicin de la cola, el taller de
reparacin de errores Burke-Fisher Eso hace que el cambio de dentro (una copia de) la cola, a
continuacin, intenta reanlisis de la vieja pila. El xito de una modificacin
es en el nmero de tokens pasados token actual se pueden analizar; Generalmente, si tres o cuatro
nuevas fichas se pueden analizar, esto se considera una reparacin totalmente exitosa.

En un lenguaje con N tipos de fichas, hay K + K + K N N posibles supresiones, inserciones y
sustituciones dentro de la ventana de smbolo K. Intentar esto muchas reparaciones no es muy
costoso, que, sobre todo teniendo en cuenta que slo se da cuando se descubre un error de sintaxis,
no ordinaria durante el anlisis.

Acciones semnticas.
Shift y reducir las acciones se juzgan y se desechan en varias ocasiones durante la bsqueda de la
mejor reparacin del error. Generadores de analizadores sintcticos por lo general usted realizar
acciones semnticas programador especificados junto con cada accin de veterano, pero el
programador no espera que estas acciones se llevarn a cabo varias veces y se descartan - pueden
tener efectos secundarios. Por lo tanto, a Burke-Fisher parser no ejecuta ninguna de las acciones
semnticas como reducciones se realizan en la pila actual, sino que espera hasta que las mismas se
llevan a cabo reducciones (de forma permanente) en la vieja pila.

Esto significa que el analizador lxico puede ser de hasta tokens K + R para apuntar a la cabeza de
la cual las acciones semnticas no han sido realizados. Si las acciones semnticas afectan anlisis
lxico - como lo hacen en C, compilar la funcin typedef - esto puede ser un problema con el enfoque
de Burke-Fisher. Para idiomas con un enfoque de la gramtica libre de contexto puro a la sintaxis,
las acciones semnticas de la demora no plantea ningn problema.

Valores semnticos para inserciones.

En la reparacin de un error de insercin, el intrprete necesita Previsto valor semntico de cada
token se inserta, de manera que las acciones semnticas se pueden realizar como si el testigo haba
venido desde el analizador lxico. Para fichas de puntuacin sin valor es necesario, pero cuando
tokens: como nmeros o identificadores deben insertarse, en donde el valor puede venir? El
generador de analizadores ML-Yacc, que utiliza Burke correccin Fischer-error, tiene una directiva
valor%, lo que permite al programador especificar qu valor se debe utilizar cuando la insercin de
cada tipo de token:

Programador sustituciones especificadas.
Algunos tipos comunes de errores no pueden ser reparados por la insercin o delecin de un nico
token, ya veces una sola insercin smbolo especial o sustitucin es muy general, son necesarios y
deben ser juzgados primero. Por lo tanto, en una especificacin de la gramtica ML-Yacc el
programador puede utilizar la directiva% de cambio para sugerir correcciones de errores a ser
juzgado en primer lugar, antes del default "eliminar o insertar cada token posible" reparaciones.


Aqu el programador est sugiriendo que a menudo los usuarios escriben "; otro ", donde su
significado" else "y as sucesivamente. Estas correcciones de errores particulares son a menudo
tiles para analizar el lenguaje de programacin ML. La insercin de 0 en el extremo Particularmente
importante es un tipo de correccin, conocido como un mbito de aplicacin ms cerca. Programas
Comnmente han dejado adicional o derecho Parntesis Los parntesis, corchetes o extrajudicial
izquierda oa la derecha, y as sucesivamente. En ML, otro tipo de construccin de anidacin es dejar
entrar final. Si el programador se olvida de cerrar un alcance que fue abierto por un
parntesis izquierdo, luego el singletoken automtica heurstica de insercin puede cerrar este
mbito donde es necesario. Pero para cerrar dejar escobas requiere la insercin de tres fichas, que
no se puede hacer de forma automtica A menos que el compilador de escritor ha sugerido "cambiar
nada para terminar en 0" como se ilustra en el comando de cambio% por encima.