mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user