|
|
In general, unary operators must be given a precedence. Sometimes a unary operator and a binary operator have the same symbolic representation but different precedences. An example is the unary and binary minus, (). Unary minus often has the same strength as multiplication, or even higher, while binary minus will have a lower strength than multiplication.
Since the representations of the two operators are the same, the keywords %left and %right cannot be used to set the precedences for both. Rather, the precedence for the unary minus is associated with the ``grammar rule'' in which it appears. The keyword %prec is used to change the precedence level associated with a particular grammar rule. Here is a grammar that involves unary and binary minuses:
%left ´+´ ´-´ %left ´´ ´/´The keyword %prec appears immediately after the body of the grammar rule, before an action or closing semicolon, and is followed by a token name or literal. It causes the precedence of the grammar rule to become that of the following token name or literal. In this example, it is used to give unary minus the same precedence as the multiplication operator, (*).%%
expr : expr ´+´ expr | expr ´-´ expr | expr ´´ expr | expr ´/´ expr | ´-´ expr %prec ´´ | NAME ;
If a token appears after one of the keywords
%left, %right, and %nonassoc,
it does not need to be declared by %token
as well, although it is not incorrect to do so.
Precedences and associativities used by yacc to resolve parsing conflicts give rise to the following disambiguating rules:
Conflicts resolved by precedence are not counted in the number of shift-reduce and reduce-reduce conflicts that yacc reports. This means that mistakes in the precedence specification may disguise errors in the input grammar. It is a good idea to be sparing with precedence and use them in a cookbook fashion until you are experienced in using it. The y.output file is very useful in deciding whether the parser is actually doing what was intended.