slv@seg.npl.co.uk (S Voogd) (01/10/91)
Dear comp.compiler-readers, While working with YACC, we came across a POSSIBLE BUG in the precedence mechanism of YACC. You can give a token a precedence and associativity by declaring this in the declaration-part of a YACC-file According to the manual you can also change the precedence and associativity of a token in the grammar-rules by using the '%prec'-mechanism. But it seems to us that this mechanism doesn't work!!! We enclose a simple desk calculator and reverse the usual precedence of '+' with '*' using the '%prec'-mechanism. It seems that the associativity of tokens can be changed.(?) But their precedence levels are now the same. Are we doing something wrong? Is this a BUG on YACC? If it is a bug, is there a way of changing the prec. and ass. of tokens ? (We really need it!) Please mail us with comments, results etc. or discuss this on the net. Simon Voogd Graeme Parkin e-mail : slv@seg.npl.co.uk gip@seg.npl.co.uk Tel : +44 81 943 7009 +44 81 943 7006 National Physical Laboratory (UK) --------Test Results----------------------------------------- normal precedences : 4+7*2 = 4+(7*2) = 18 2*7+4 = (2*7)+4 = 18 reversed precedences : 4+7*2 = (4+7)*2 = 22 2*7+4 = 2*(7+4) = 22 BUT the enclosed calculator gives the following results : 4+7*2 = 22 [ = (4+7)*2 ] 2*7+4 = 18 [ = (2*7)+4 ] (surely should be 22 !!!!!) --------Simple Desk Calculator------------------------------- %{ #include <stdio.h> #define YYSTYPE double %} %token NUMBER %left PLUS %left MUL %% lines : lines expr '\n' {printf("%g\n", $2); } | lines '\n' | | error '\n' { yyerror("reenter last line:"); yyerrok; } ; expr : expr PLUS expr %prec MUL { $$ = $1 + $3; } | expr MUL expr %prec PLUS { $$ = $1 * $3; } | NUMBER ; %% yylex() { int c; while((c = getchar()) == ' ') {} if(isdigit(c)) { yylval = c - '0'; return(NUMBER); } if(c == '+') { yylval = PLUS; return(PLUS); } if(c == '*') { yylval = MUL; return(MUL); } if(c == EOF) { yylval = 0; return(EOF); } return(c); } yywrap(){}; yyerror(s) char *s;{ fprintf(stderr,"%s\n",s); }; main(){ return(yyparse() ); } ------------------------------------------------------------- [This does appear to confuse yacc's precedence mechanism -- the two productions are indeed treated as of equal precedence. The standard unary minus precedence does work, I haven't narrowed the bug further. -John] -- Send compilers articles to compilers@iecc.cambridge.ma.us or {ima | spdcc | world}!iecc!compilers. Meta-mail to compilers-request.