Bell 32V development
[unix-history] / usr / doc / yacc / ss6
CommitLineData
2240a03d
TL
1.SH
26: Precedence
3.PP
4There is one common situation
5where the rules given above for resolving conflicts are not sufficient;
6this is in the parsing of arithmetic expressions.
7Most of the commonly used constructions for arithmetic expressions can be naturally
8described by the notion of
9.I precedence
10levels for operators, together with information about left
11or right associativity.
12It turns out that ambiguous grammars with appropriate disambiguating rules
13can be used to create parsers that are faster and easier to
14write than parsers constructed from unambiguous grammars.
15The basic notion is to write grammar rules
16of the form
17.DS
18expr : expr OP expr
19.DE
20and
21.DS
22expr : UNARY expr
23.DE
24for all binary and unary operators desired.
25This creates a very ambiguous grammar, with many parsing conflicts.
26As disambiguating rules, the user specifies the precedence, or binding
27strength, of all the operators, and the associativity
28of the binary operators.
29This information is sufficient to allow Yacc to resolve the parsing conflicts
30in accordance with these rules, and construct a parser that realizes the desired
31precedences and associativities.
32.PP
33The precedences and associativities are attached to tokens in the declarations section.
34This is done by a series of lines beginning with a Yacc keyword: %left, %right,
35or %nonassoc, followed by a list of tokens.
36All of the tokens on the same line are assumed to have the same precedence level
37and associativity; the lines are listed in
38order of increasing precedence or binding strength.
39Thus,
40.DS
41%left \'+\' \'\-\'
42%left \'*\' \'/\'
43.DE
44describes the precedence and associativity of the four arithmetic operators.
45Plus and minus are left associative, and have lower precedence than
46star and slash, which are also left associative.
47The keyword %right is used to describe right associative operators,
48and the keyword %nonassoc is used to describe operators, like
49the operator .LT. in Fortran, that may not associate with themselves; thus,
50.DS
51A .LT. B .LT. C
52.DE
53is illegal in Fortran, and such an operator would be described with the keyword
54%nonassoc in Yacc.
55As an example of the behavior of these declarations, the description
56.DS
57%right \'=\'
58%left \'+\' \'\-\'
59%left \'*\' \'/\'
60
61%%
62
63expr : expr \'=\' expr
64 | expr \'+\' expr
65 | expr \'\-\' expr
66 | expr \'*\' expr
67 | expr \'/\' expr
68 | NAME
69 ;
70.DE
71might be used to structure the input
72.DS
73a = b = c*d \- e \- f*g
74.DE
75as follows:
76.DS
77a = ( b = ( ((c*d)\-e) \- (f*g) ) )
78.DE
79When this mechanism is used,
80unary operators must, in general, be given a precedence.
81Sometimes a unary operator and a binary operator
82have the same symbolic representation, but different precedences.
83An example is unary and binary \'\-\'; unary minus may be given the same
84strength as multiplication, or even higher, while binary minus has a lower strength than
85multiplication.
86The keyword, %prec, changes the precedence level associated with a particular grammar rule.
87%prec appears immediately after the body of the grammar rule, before the action or closing semicolon,
88and is followed by a token name or literal.
89It
90causes the precedence of the grammar rule to become that of the following token name or literal.
91For example, to make unary minus have the same precedence as multiplication the rules might resemble:
92.DS
93%left \'+\' \'\-\'
94%left \'*\' \'/\'
95
96%%
97
98expr : expr \'+\' expr
99 | expr \'\-\' expr
100 | expr \'*\' expr
101 | expr \'/\' expr
102 | \'\-\' expr %prec \'*\'
103 | NAME
104 ;
105.DE
106.PP
107A token declared
108by %left, %right, and %nonassoc need not be, but may be, declared by %token as well.
109.PP
110The precedences and associativities are used by Yacc to
111resolve parsing conflicts; they give rise to disambiguating rules.
112Formally, the rules work as follows:
113.IP 1.
114The precedences and associativities are recorded for those tokens and literals
115that have them.
116.IP 2.
117A precedence and associativity is associated with each grammar rule; it is the precedence
118and associativity of the last token or literal in the body of the rule.
119If the %prec construction is used, it overrides this default.
120Some grammar rules may have no precedence and associativity associated with them.
121.IP 3.
122When there is a reduce/reduce conflict, or there is a shift/reduce conflict
123and either the input symbol or the grammar rule has no precedence and associativity,
124then the two disambiguating rules given at the beginning of the section are used,
125and the conflicts are reported.
126.IP 4.
127If there is a shift/reduce conflict, and both the grammar rule and the input character
128have precedence and associativity associated with them, then the conflict is resolved
129in favor of the action (shift or reduce) associated with the higher precedence.
130If the precedences are the same, then the associativity is used; left
131associative implies reduce, right associative implies shift, and nonassociating
132implies error.
133.PP
134Conflicts resolved by precedence are not counted in the number of shift/reduce and reduce/reduce
135conflicts reported by Yacc.
136This means that mistakes in the specification of precedences may
137disguise errors in the input grammar; it is a good idea to be sparing
138with precedences, and use them in an essentially ``cookbook'' fashion,
139until some experience has been gained.
140The
141.I y.output
142file
143is very useful in deciding whether the parser is actually doing
144what was intended.