documentación
documentación
documentación
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