doc: refer to cex from sections dealing with conflicts

The documentation about -Wcex should be put forward.

* doc/bison.texi: Refer to -Wcex from the sections about conflicts.
This commit is contained in:
Akim Demaille
2020-07-28 07:41:33 +02:00
parent e63f22703e
commit 6accee7716
2 changed files with 68 additions and 39 deletions

2
NEWS
View File

@@ -2,6 +2,8 @@ GNU Bison NEWS
* Noteworthy changes in release ?.? (????-??-??) [?] * Noteworthy changes in release ?.? (????-??-??) [?]
Improvements and fixes in the documentation.
* Noteworthy changes in release 3.7 (2020-07-23) [stable] * Noteworthy changes in release 3.7 (2020-07-23) [stable]

View File

@@ -8315,7 +8315,53 @@ write an unambiguous grammar, but that is very hard to do in this case.)
This particular ambiguity was first encountered in the specifications of 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 assist the grammar author in understanding the nature of each conflict,
Bison can be asked to generate ``counterexamples''. In the present case it
actually even proves that the grammar is ambiguous by exhibiting a string
with two different parses:
@macro danglingElseCex
@group
@ifnottex
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"else" stmt}
Shift derivation
@yellow{if_stmt}
@yellow{↳ "if" expr "then"} @green{stmt}
@green{↳} @blue{if_stmt}
@blue{↳ "if" expr "then" stmt} @red{•} @blue{"else" stmt}
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
Reduce derivation
@yellow{if_stmt}
@yellow{↳ "if" expr "then"} @green{stmt} @yellow{"else" stmt}
@green{↳} @blue{if_stmt}
@blue{↳ "if" expr "then" stmt} @red{•}
@end ifnottex
@iftex
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"else" stmt}
Shift derivation
@yellow{if_stmt}
@yellow{@arrow{} "if" expr "then"} @green{stmt}
@green{@arrow{}} @blue{if_stmt}
@blue{@arrow{} "if" expr "then" stmt} @red{•} @blue{"else" stmt}
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
Reduce derivation
@yellow{if_stmt}
@yellow{@arrow{} "if" expr "then"} @green{stmt} @yellow{"else" stmt}
@green{@arrow{}} @blue{if_stmt}
@blue{@arrow{} "if" expr "then" stmt} @red{•}
@end iftex
@end group
@end macro
@example
@danglingElseCex
@end example
@noindent
@xref{Counterexamples}, for more details.
@sp 1
To avoid warnings from Bison about predictable, @emph{legitimate} shift/reduce
conflicts, you can 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
@@ -8706,7 +8752,8 @@ maybeword:
@end example @end example
@noindent @noindent
The error is an ambiguity: there is more than one way to parse a single The error is an ambiguity: as counterexample generation would demonstrate
(@pxref{Counterexamples}), there is more than one way to parse a single
@code{word} into a @code{sequence}. It could be reduced to a @code{word} into a @code{sequence}. It could be reduced to a
@code{maybeword} and then into a @code{sequence} via the second rule. @code{maybeword} and then into a @code{sequence} via the second rule.
Alternatively, nothing-at-all could be reduced into a @code{sequence} Alternatively, nothing-at-all could be reduced into a @code{sequence}
@@ -8903,12 +8950,14 @@ name_list:
It would seem that this grammar can be parsed with only a single token of It would seem that this grammar can be parsed with only a single token of
lookahead: when a @code{param_spec} is being read, an @code{"id"} is a lookahead: when a @code{param_spec} is being read, an @code{"id"} is a
@code{name} if a comma or colon follows, or a @code{type} if another @code{name} if a comma or colon follows, or a @code{type} if another
@code{"id"} follows. In other words, this grammar is LR(1). @code{"id"} follows. In other words, this grammar is LR(1). Yet Bison
finds one reduce/reduce conflict, for which counterexample generation
(@pxref{Counterexamples}) would find a @emph{nonunifying} example.
@cindex LR @cindex LR
@cindex LALR @cindex LALR
However, for historical reasons, Bison cannot by default handle all This is because Bison does not handle all LR(1) grammars @emph{by default},
LR(1) grammars. for historical reasons.
In this grammar, two contexts, that after an @code{"id"} at the beginning In this grammar, two contexts, that after an @code{"id"} at the beginning
of a @code{param_spec} and likewise at the beginning of a of a @code{param_spec} and likewise at the beginning of a
@code{return_spec}, are similar enough that Bison assumes they are the @code{return_spec}, are similar enough that Bison assumes they are the
@@ -9883,6 +9932,9 @@ and understand the parser run-time traces (@pxref{Tracing}).
@node Counterexamples @node Counterexamples
@section Generation of Counterexamples @section Generation of Counterexamples
@cindex cex
@cindex counterexamples
@cindex conflict counterexamples
Solving conflicts is probably the most delicate part of the design of an LR Solving conflicts is probably the most delicate part of the design of an LR
parser, as demonstrated by the number of sections devoted to them in this parser, as demonstrated by the number of sections devoted to them in this
@@ -9899,8 +9951,8 @@ That task is made much easier thanks to the generation of counterexamples,
initially developed by Chinawat Isradisaikul and Andrew Myers initially developed by Chinawat Isradisaikul and Andrew Myers
@pcite{Isradisaikul 2015}. @pcite{Isradisaikul 2015}.
As a first example, see the example grammar of @ref{Shift/Reduce}, which As a first example, see the grammar of @ref{Shift/Reduce}, which features
features one shift/reduce conflict: one shift/reduce conflict:
@c see doc/if-then-else.y @c see doc/if-then-else.y
@example @example
@@ -9917,40 +9969,11 @@ output is actually in color)}:
@example @example
if-then-else.y: @dwarning{warning}: 1 shift/reduce conflict [@dwarning{-Wconflicts-sr}] if-then-else.y: @dwarning{warning}: 1 shift/reduce conflict [@dwarning{-Wconflicts-sr}]
if-then-else.y: @dwarning{warning}: shift/reduce conflict on token "else" [@dwarning{-Wcounterexamples}] if-then-else.y: @dwarning{warning}: shift/reduce conflict on token "else" [@dwarning{-Wcounterexamples}]
@group @danglingElseCex
@ifnottex
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"else" stmt}
Shift derivation
@yellow{if_stmt}
@yellow{↳ "if" expr "then"} @green{stmt}
@green{↳} @blue{if_stmt}
@blue{↳ "if" expr "then" stmt} @red{•} @blue{"else" stmt}
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
Reduce derivation
@yellow{if_stmt}
@yellow{↳ "if" expr "then"} @green{stmt} @yellow{"else" stmt}
@green{↳} @blue{if_stmt}
@blue{↳ "if" expr "then" stmt} @red{•}
@end ifnottex
@iftex
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"else" stmt}
Shift derivation
@yellow{if_stmt}
@yellow{@arrow{} "if" expr "then"} @green{stmt}
@green{@arrow{}} @blue{if_stmt}
@blue{@arrow{} "if" expr "then" stmt} @red{•} @blue{"else" stmt}
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
Reduce derivation
@yellow{if_stmt}
@yellow{@arrow{} "if" expr "then"} @green{stmt} @yellow{"else" stmt}
@green{@arrow{}} @blue{if_stmt}
@blue{@arrow{} "if" expr "then" stmt} @red{•}
@end iftex
@end group
@end example @end example
This shows two different derivations for one single expression. That This shows two different derivations for one single expression, which proves
demonstrates that the grammar is ambiguous. that the grammar is ambiguous.
@sp 1 @sp 1
@@ -15627,6 +15650,10 @@ permitted. @xref{Language and Grammar}.
A sequence of tokens and/or nonterminals, with one dot, that demonstrates a A sequence of tokens and/or nonterminals, with one dot, that demonstrates a
conflict. The dot marks the place where the conflict occurs. conflict. The dot marks the place where the conflict occurs.
@cindex unifying counterexample
@cindex counterexample, unifying
@cindex nonunifying counterexample
@cindex counterexample, nonunifying
A @emph{unifying} counterexample is a single string that has two different A @emph{unifying} counterexample is a single string that has two different
parses; its existence proves that the grammar is ambiguous. When a unifying parses; its existence proves that the grammar is ambiguous. When a unifying
counterexample cannot be found in reasonable time, a @emph{nonunifying} counterexample cannot be found in reasonable time, a @emph{nonunifying}