

token no modifica la precedencia. Si lo hacen las declaraciones realizadas usando las palabras left, right y nonassoc. Los tokens declarados en la misma línea
tienen igual precedencia. La precedencia es mayor cuanto mas abajo en
el texto. Así, en el ejemplo que sigue, el token * tiene
mayor precedencia que + pero la misma que /.
expr : expr '+' expr
tiene la precedencia del token +.
Por tanto es imposible declarar dos tokens con diferente asociatividad y la misma precedencia.
prec token, donde token es un token
con la precedencia que deseamos. Vea el uso del token dummy en el siguiente ejercicio.
%{
#define YYSTYPE double
#include <stdio.h>
%}
%token NUMBER
%left '@'
%right '&' dummy
%%
list
:
| list '\n'
| list e
;
e : NUMBER
| e '&' e
| e '@' e %prec dummy
;
%%
extern FILE * yyin;
main(int argc, char **argv) {
if (argc > 1) yyin = fopen(argv[1],"r");
yydebug = 1;
yyparse();
}
yyerror(char *s) {
printf("%s\n",s);
}
yacc 11.2.1
Responda a las siguientes cuestiones:
4@3@5, 4&3&5, 4@3&5, 4&3@5.
e : e '@' e?
0 $accept : list $end 1 list : 2 | list '\n' 3 | list e 4 e : NUMBER 5 | e '&' e 6 | e '@' e
state 0 $accept : . list $end (0) list : . (1) . reduce 1 list goto 1 state 1 $accept : list . $end (0) list : list . '\n' (2) list : list . e (3) $end accept NUMBER shift 2 '\n' shift 3 . error e goto 4 state 2 e : NUMBER . (4) . reduce 4 state 3 list : list '\n' . (2) . reduce 2 state 4 list : list e . (3) e : e . '&' e (5) e : e . '@' e (6) '@' shift 5 '&' shift 6 $end reduce 3 NUMBER reduce 3 '\n' reduce 3 |
state 5 e : e '@' . e (6) NUMBER shift 2 . error e goto 7 state 6 e : e '&' . e (5) NUMBER shift 2 . error e goto 8 state 7 e : e . '&' e (5) e : e . '@' e (6) e : e '@' e . (6) '&' shift 6 $end reduce 6 NUMBER reduce 6 '@' reduce 6 '\n' reduce 6 state 8 e : e . '&' e (5) e : e '&' e . (5) e : e . '@' e (6) '&' shift 6 $end reduce 5 NUMBER reduce 5 '@' reduce 5 '\n' reduce 5 |
7 terminals, 3 nonterminals 7 grammar rules, 9 states
1@2&3, al establecer la variable yydebug = 1
y definir la macro YYDEBUG:
$ hocprec
yydebug: state 0, reducing by rule 1 (list :)
yydebug: after reduction, shifting from state 0 to state 1
1@2&3
yydebug: state 1, reading 257 (NUMBER)
yydebug: state 1, shifting to state 2
yydebug: state 2, reducing by rule 4 (e : NUMBER)
yydebug: after reduction, shifting from state 1 to state 4
yydebug: state 4, reading 64 ('@')
yydebug: state 4, shifting to state 5
yydebug: state 5, reading 257 (NUMBER)
yydebug: state 5, shifting to state 2
yydebug: state 2, reducing by rule 4 (e : NUMBER)
yydebug: after reduction, shifting from state 5 to state 7
yydebug: state 7, reading 38 ('&')
yydebug: state 7, shifting to state 6
%left '@'?. ¿O quizá es porque la precedencia de @
es menor que la de &? La respuesta es que la precedencia
asignada por la declaración
e : e '@' e %prec dummy
& con su misma precedencia.
Al pasar a ser asociativa a derechas (debido a que
dummy lo es), se debe desplazar y no reducir.
1&2@3. Compara tus predicciones con los resultados.
$ hocprec
yydebug: state 0, reducing by rule 1 (list :)
yydebug: after reduction, shifting from state 0 to state 1
1&2@3
yydebug: state 1, reading 257 (NUMBER)
yydebug: state 1, shifting to state 2
yydebug: state 2, reducing by rule 4 (e : NUMBER)
yydebug: after reduction, shifting from state 1 to state 4
yydebug: state 4, reading 38 ('&')
yydebug: state 4, shifting to state 6
yydebug: state 6, reading 257 (NUMBER)
yydebug: state 6, shifting to state 2
yydebug: state 2, reducing by rule 4 (e : NUMBER)
yydebug: after reduction, shifting from state 6 to state 8
yydebug: state 8, reading 64 ('@')
yydebug: state 8, reducing by rule 5 (e : e '&' e)
e
e & e
@. La regla tiene mayor precedencia
que el token,dado que la precedencia de la regla es la de
&.

