mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-16 15:53:03 +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.
|
* Using Precedence:: How to specify precedence in Bison grammars.
|
||||||
* Precedence Examples:: How these features are used in the previous example.
|
* Precedence Examples:: How these features are used in the previous example.
|
||||||
* How Precedence:: How they work.
|
* How Precedence:: How they work.
|
||||||
|
* Non Operators:: Using precedence for general conflicts.
|
||||||
|
|
||||||
Tuning LR
|
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.
|
Algol 60 and is called the ``dangling @code{else}'' ambiguity.
|
||||||
|
|
||||||
To avoid warnings from Bison about predictable, legitimate shift/reduce
|
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
|
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
|
is exactly @var{n}, and Bison will report an error if there is a
|
||||||
different number.
|
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
|
The definition of @code{if_stmt} above is solely to blame for the
|
||||||
conflict, but the conflict does not actually appear without additional
|
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.
|
* Using Precedence:: How to specify precedence in Bison grammars.
|
||||||
* Precedence Examples:: How these features are used in the previous example.
|
* Precedence Examples:: How these features are used in the previous example.
|
||||||
* How Precedence:: How they work.
|
* How Precedence:: How they work.
|
||||||
|
* Non Operators:: Using precedence for general conflicts.
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node Why Precedence
|
@node Why Precedence
|
||||||
@@ -6828,6 +6835,44 @@ resolved.
|
|||||||
Not all rules and not all tokens have precedence. If either the rule or
|
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.
|
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
|
@node Contextual Precedence
|
||||||
@section Context-Dependent Precedence
|
@section Context-Dependent Precedence
|
||||||
@cindex context-dependent precedence
|
@cindex context-dependent precedence
|
||||||
|
|||||||
Reference in New Issue
Block a user