doc: fix the dangling else with precedence directives

* doc/bison.texi (Non Operators): New node.
(Shift/Reduce): Point to it.
Don't promote "%expect n" too much.
This commit is contained in:
Akim Demaille
2012-11-22 15:16:07 +01:00
parent 534cee7ae8
commit c28cd5dc5a

View File

@@ -276,6 +276,7 @@ Operator Precedence
* Using Precedence:: How to specify precedence in Bison grammars.
* Precedence Examples:: How these features are used in the previous example.
* How Precedence:: How they work.
* Non Operators:: Using precedence for general conflicts.
Tuning LR
@@ -6665,11 +6666,16 @@ This particular ambiguity was first encountered in the specifications of
Algol 60 and is called the ``dangling @code{else}'' ambiguity.
To avoid warnings from Bison about predictable, legitimate shift/reduce
conflicts, use the @code{%expect @var{n}} declaration.
conflicts, you can use the @code{%expect @var{n}} declaration.
There will be no warning as long as the number of shift/reduce conflicts
is exactly @var{n}, and Bison will report an error if there is a
different number.
@xref{Expect Decl, ,Suppressing Conflict Warnings}.
@xref{Expect Decl, ,Suppressing Conflict Warnings}. However, we don't
recommend the use of @code{%expect} (except @samp{%expect 0}!), as an equal
number of conflicts does not mean that they are the @emph{same}. When
possible, you should rather use precedence directives to @emph{fix} the
conflicts explicitly (@pxref{Non Operators,, Using Precedence For Non
Operators}).
The definition of @code{if_stmt} above is solely to blame for the
conflict, but the conflict does not actually appear without additional
@@ -6714,6 +6720,7 @@ shift and when to reduce.
* Using Precedence:: How to specify precedence in Bison grammars.
* Precedence Examples:: How these features are used in the previous example.
* How Precedence:: How they work.
* Non Operators:: Using precedence for general conflicts.
@end menu
@node Why Precedence
@@ -6828,6 +6835,44 @@ resolved.
Not all rules and not all tokens have precedence. If either the rule or
the lookahead token has no precedence, then the default is to shift.
@node Non Operators
@subsection Using Precedence For Non Operators
Using properly precedence and associativity directives can help fixing
shift/reduce conflicts that do not involve arithmetics-like operators. For
instance, the ``dangling @code{else}'' problem (@pxref{Shift/Reduce, ,
Shift/Reduce Conflicts}) can be solved elegantly in two different ways.
In the present case, the conflict is between the token @code{"else"} willing
to be shifted, and the rule @samp{if_stmt: "if" expr "then" stmt}, asking
for reduction. By default, the precedence of a rule is that of its last
token, here @code{"then"}, so the conflict will be solved appropriately
by giving @code{"else"} a precedence higher than that of @code{"then"}, for
instance as follows:
@example
@group
%nonassoc "then"
%nonassoc "else"
@end group
@end example
Alternatively, you may give both tokens the same precedence, in which case
associativity is used to solve the conflict. To preserve the shift action,
use right associativity:
@example
%right "then" "else"
@end example
Neither solution is perfect however. Since Bison does not provide, so far,
support for ``scoped'' precedence, both force you to declare the precedence
of these keywords with respect to the other operators your grammar.
Therefore, instead of being warned about new conflicts you would be unaware
of (e.g., a shift/reduce conflict due to @samp{if test then 1 else 2 + 3}
being ambiguous: @samp{if test then 1 else (2 + 3)} or @samp{(if test then 1
else 2) + 3}?), the conflict will be already ``fixed''.
@node Contextual Precedence
@section Context-Dependent Precedence
@cindex context-dependent precedence