27.08.2013 Views

documentación

documentación

documentación

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

expr - expr - expr<br />

El parser podría entonces aplicar la regla a los tres símbolos de más a la derecha,<br />

reduciendo entonces a expr, dejando:<br />

expr - expr<br />

Ahora la regla puede ser reducida una vez más. El efecto es tomar la interpretación<br />

correspondiente a la asociatividad a derecha. Así, habiendo leído:<br />

expr - expr<br />

el parser puede hacer una de dos acciones legales, un shift o una reducción. No tiene forma de<br />

decidir entre ambas. Esto es un conflicto shift-reduce. El parser puede también tener que elegir<br />

entre dos reducciones legales. Este es un conflicto reduce-reduce. Notar que nunca hay<br />

conflictos shift-shift.<br />

Cuando hay conflictos shift-reduce o reduce-reduce, Yacc de todos modos produce un<br />

parser. Lo hace seleccionando una de las acciones legales cuando tiene que elegir. Para ello, el<br />

programa Yacc provee dos reglas de desambiguación:<br />

1. En un conflicto shift-reduce, la acción por defecto es el shift<br />

2. En un conflicto reduce-reduce, el defecto es reducir por la primera regla (en la<br />

especificación Yacc)<br />

La regla 1 implica que las reducciones son diferidas en favor de los shifts cuando es<br />

necesario elegir entre ambas acciones. La regla 2 le da al usuario el control sobre el<br />

comportamiento del parser en esta situación, aunque los conflictos reduce-reduce deberían ser<br />

evitados en lo posible.<br />

El uso de acciones dentro de las reglas puede también causar conflictos si la acción debe<br />

hacerse antes que el parser pueda estar seguro de cual regla está reconociendo. En estos casos,<br />

la aplicación de las reglas de desambiguación es inapropiada, y llevaría a un parser incorrecto.<br />

Por esta razón, Yacc siempre reporta el número de conflictos shift-reduce y reduce-reduce<br />

resueltos por la Regla 1 y por la Regla 2.<br />

En general, si es posible aplicar las reglas de desambiguación para producir un parser<br />

correcto, también es posible reescribir las reglas de la gramática de modo que las mismas<br />

entradas puedan ser leídas sin conflictos. Por esta razón, la mayoría de los generadores de<br />

parsers previos, consideraban los conflictos como errores fatales. Sin embargo, Yacc producirá<br />

parsers aún en presencia de conflictos.<br />

Como un ejemplo del poder de las reglas de desambiguación, consideremos:<br />

sent : IF ´(´ cond ´)´ sent<br />

| IF ´(´ cond ´)´ sent ELSE sent<br />

;<br />

que es un fragmento de un lenguaje de programación correspondiente a una sentencia if-thenelse.<br />

En estas reglas, IF y ELSE son tokens, cond es un símbolo no terminal describiendo<br />

expresiones condicionales (lógicas), y sent es un símbolo no terminal describiendo sentencias.<br />

Llamaremos regla if simple a la primera, y regla if-else, a la segunda.<br />

Estas dos reglas forman una construcción ambigua porque una entrada de la forma:<br />

14

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!