summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorPaul Hilfinger <hilfingr@eecs.berkeley.edu>2013-02-26 16:28:36 -0800
committerAkim Demaille <akim.demaille@gmail.com>2018-11-21 22:08:47 +0100
commitb34b12c4f9b920ffcfb9f94ce7a894afa3ba8fed (patch)
treeafeb6a189342746949cac34a0059b09343223df0 /doc
parent487a2a9ecae81a401e1eb613837cbeb02df45f6e (diff)
downloadbison-b34b12c4f9b920ffcfb9f94ce7a894afa3ba8fed.tar.gz
allow %expect and %expect-rr modifiers on individual rules
This change allows one to document (and check) which rules participate in shift/reduce and reduce/reduce conflicts. This is particularly important GLR parsers, where conflicts are a normal occurrence. For example, %glr-parser %expect 1 %% ... argument_list: arguments %expect 1 | arguments ',' | %empty ; arguments: expression | argument_list ',' expression ; ... Looking at the output from -v, one can see that the shift-reduce conflict here is due to the fact that the parser does not know whether to reduce arguments to argument_list until it sees the token AFTER the following ','. By marking the rule with %expect 1 (because there is a conflict in one state), we document the source of the 1 overall shift- reduce conflict. In GLR parsers, we can use %expect-rr in a rule for reduce/reduce conflicts. In this case, we mark each of the conflicting rules. For example, %glr-parser %expect-rr 1 %% stmt: target_list '=' expr ';' | expr_list ';' ; target_list: target | target ',' target_list ; target: ID %expect-rr 1 ; expr_list: expr | expr ',' expr_list ; expr: ID %expect-rr 1 | ... ; In a statement such as x, y = 3, 4; the parser must reduce x to a target or an expr, but does not know which until it sees the '='. So we notate the two possible reductions to indicate that each conflicts in one rule. See https://lists.gnu.org/archive/html/bison-patches/2013-02/msg00105.html. * doc/bison.texi (Suppressing Conflict Warnings): Document %expect, %expect-rr in grammar rules. * src/conflicts.c (count_state_rr_conflicts): Adjust comment. (rule_has_state_sr_conflicts): New static function. (count_rule_sr_conflicts): New static function. (rule_nast_state_rr_conflicts): New static function. (count_rule_rr_conflicts): New static function. (rule_conflicts_print): New static function. (conflicts_print): Also use rule_conflicts_print to report on individual rules. * src/gram.h (struct rule): Add new fields expected_sr_conflicts, expected_rr_conflicts. * src/reader.c (grammar_midrule_action): Transfer expected_sr_conflicts, expected_rr_conflicts to new rule, and turn off in current_rule. (grammar_current_rule_expect_sr): New function. (grammar_current_rule_expect_rr): New function. (packgram): Transfer expected_sr_conflicts, expected_rr_conflicts to new rule. * src/reader.h (grammar_current_rule_expect_sr): New function. (grammar_current_rule_expect_rr): New function. * src/symlist.c (symbol_list_sym_new): Initialize expected_sr_conflicts, expected_rr_conflicts. * src/symlist.h (struct symbol_list): Add new fields expected_sr_conflicts, expected_rr_conflicts. * tests/conflicts.at: Add tests "%expect in grammar rule not enough", "%expect in grammar rule right.", "%expect in grammar rule too much."
Diffstat (limited to 'doc')
-rw-r--r--doc/bison.texi67
1 files changed, 65 insertions, 2 deletions
diff --git a/doc/bison.texi b/doc/bison.texi
index 72f28fc2..fe580bde 100644
--- a/doc/bison.texi
+++ b/doc/bison.texi
@@ -5254,6 +5254,53 @@ in GLR parsers, using the declaration:
%expect-rr @var{n}
@end example
+You may wish to be more specific in your
+specification of expected conflicts. To this end, you can also attach
+@code{%expect} and @code{%expect-rr} modifiers to individual rules.
+The interpretation of these modifiers differs from their use as
+declarations. When attached to rules, they indicate the number of states
+in which the rule is involved in a conflict. You will need to consult the
+output resulting from @samp{-v} to determine appropriate numbers to use.
+For example, for the following grammar fragment, the first rule for
+@code{empty_dims} appears in two states in which the @samp{[} token is a
+lookahead. Having determined that, you can document this fact with an
+@code{%expect} modifier as follows:
+
+@example
+dims:
+ empty_dims
+| '[' expr ']' dims
+;
+
+empty_dims:
+ %empty %expect 2
+| empty_dims '[' ']'
+;
+@end example
+
+Mid-rule actions generate implicit rules that are also subject to conflicts
+(@pxref{Midrule Conflicts,, Conflicts due to Midrule Actions}). To attach
+an @code{%expect} or @code{%expect-rr} annotation to an implicit
+mid-rule action's rule, put it before the action. For example,
+
+@example
+%glr-parser
+%expect-rr 1
+
+%%
+
+clause:
+ "condition" %expect-rr 1 @{ value_mode(); @} '(' exprs ')'
+| "condition" %expect-rr 1 @{ class_mode(); @} '(' types ')'
+;
+@end example
+
+@noindent
+Here, the appropriate mid-rule action will not be determined until after
+the @samp{(} token is shifted. Thus,
+the two actions will clash with each other, and we should expect one
+reduce/reduce conflict for each.
+
In general, using @code{%expect} involves these steps:
@itemize @bullet
@@ -5269,8 +5316,17 @@ go back to the beginning.
@item
Add an @code{%expect} declaration, copying the number @var{n} from the
-number which Bison printed. With GLR parsers, add an
+number that Bison printed. With GLR parsers, add an
@code{%expect-rr} declaration as well.
+
+@item
+Optionally, count up the number of states in which one or more
+conflicted reductions for particular rules appear and add these numbers
+to the affected rules as @code{%expect-rr} or @code{%expect} modifiers
+as appropriate. Rules that are in conflict appear in the output listing
+surrounded by square brackets or, in the case of reduce/reduce conflicts,
+as reductions having the same lookahead symbol as a square-bracketed
+reduction in the same state.
@end itemize
Now Bison will report an error if you introduce an unexpected conflict,
@@ -5491,7 +5547,14 @@ Start-Symbol}).
@end deffn
@deffn {Directive} %expect
-Declare the expected number of shift-reduce conflicts
+Declare the expected number of shift-reduce conflicts, either overall or
+for a given rule
+(@pxref{Expect Decl, ,Suppressing Conflict Warnings}).
+@end deffn
+
+@deffn {Directive} %expect-rr
+Declare the expected number of reduce-reduce conflicts, either overall or
+for a given rule
(@pxref{Expect Decl, ,Suppressing Conflict Warnings}).
@end deffn