JavaCUP - Especificación: Precedencias y asociatividades

Especificación de la precedencia y asociatividad

La tercer sección de la especificación, que es opcional, especifica la asociatividad y precedencia de los terminales. En general, se utiliza cuando se trabaja con una gramática ambigua, justamente para desambiguar las expresiones, por medio de la precedencia y la asociatividad, es decir que se utiliza para resolver los conflictos shift/reduce. Existen tres clases de declaraciones de precedencia y asociatividad:

precedence left terminal[, terminal...];
precedence right terminal[, terminal...];
precedence nonassoc terminal[, terminal...];

la lista separada por comas (",") indica que los terminales deberían tener la asociatividad epecificada a ese nivel de precedencia y la precedencia de esa declaración. El orden de precedencia, de mayor a menor, es ascendente, es decir que la última declaración de precedencia es la que posee mayor precedencia.

CUP le asigna a cada uno de los terminales una precedencia de acuerdo a estas declaraciones. Cualquier terminal que no aparezca en las declaraciones posee menor precedencia que todos los declarados.
CUP también le asigna una precedencia a cada una de las producciones, la cual es igual a la precedencia del último terminal de la producción. Si la producción no tiene terminales, entonces posee el nivel más bajo de precedencia.

A cada uno de los terminales usados en las declaraciones de precedencia/asociatividad, se le asigna una característica de asociatividad. Hay tres clases de asociatividad, y pueden ser a izquierda (left), a derecha (right) o no asociativo (nonassoc). Las asociatividades también se utilizan para resolver conflictos shift/reduce, pero sólo en el caso en que las precedencias sean iguales. Si la asociatividad del terminal que puede ser shifteado es left, entonces se ejecuta un reduce; en otro caso, es shifteado al stack, dado que las reducciones ocurren de derecha a izquierda.

Los terminales que no aparecen en las declaraciones de precedencia y asociatividad se tratan con la más baja precedencia. Si se produce un error shift/reduce que involucre a tales terminales, el conflicto no puede resolverse, y el error será reportado.