1 # Exercising Bison Grammar Reduction. -*- Autotest -*-
3 # Copyright (C) 2001-2002, 2007-2015, 2018-2021 Free Software
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <https://www.gnu.org/licenses/>.
19 AT_BANNER([[Grammar Reduction.]])
22 ## ------------------- ##
23 ## Useless Terminals. ##
24 ## ------------------- ##
26 AT_SETUP([Useless Terminals])
47 AT_BISON_CHECK([[input.y]])
49 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
50 [[Terminals unused in grammar
66 ## ---------------------- ##
67 ## Useless Nonterminals. ##
68 ## ---------------------- ##
70 AT_SETUP([Useless Nonterminals])
71 AT_BISON_OPTION_PUSHDEFS
75 ]AT_YYERROR_DECLARE_EXTERN[
76 ]AT_YYLEX_DECLARE_EXTERN[
89 AT_BISON_CHECK([[input.y]], 0, [],
90 [[input.y: warning: 3 nonterminals useless in grammar [-Wother]
91 input.y: warning: 3 rules useless in grammar [-Wother]
92 input.y:11.1-8: warning: nonterminal useless in grammar: useless1 [-Wother]
93 input.y:12.1-8: warning: nonterminal useless in grammar: useless2 [-Wother]
94 input.y:13.1-8: warning: nonterminal useless in grammar: useless3 [-Wother]
97 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
98 [[Nonterminals useless in grammar
102 Rules useless in grammar
108 # Make sure the generated parser is correct.
109 AT_COMPILE([input.o])
111 AT_BISON_OPTION_POPDEFS
116 ## --------------- ##
118 ## --------------- ##
120 AT_SETUP([Useless Rules])
122 AT_BISON_OPTION_PUSHDEFS
123 AT_KEYWORDS([report])
127 ]AT_YYERROR_DECLARE_EXTERN[
128 ]AT_YYLEX_DECLARE_EXTERN[
146 AT_BISON_CHECK([[-fcaret input.y]], 0, [],
147 [[input.y: warning: 9 nonterminals useless in grammar [-Wother]
148 input.y: warning: 9 rules useless in grammar [-Wother]
149 input.y:10.1-8: warning: nonterminal useless in grammar: useless1 [-Wother]
152 input.y:11.1-8: warning: nonterminal useless in grammar: useless2 [-Wother]
155 input.y:12.1-8: warning: nonterminal useless in grammar: useless3 [-Wother]
158 input.y:13.1-8: warning: nonterminal useless in grammar: useless4 [-Wother]
161 input.y:14.1-8: warning: nonterminal useless in grammar: useless5 [-Wother]
164 input.y:15.1-8: warning: nonterminal useless in grammar: useless6 [-Wother]
167 input.y:16.1-8: warning: nonterminal useless in grammar: useless7 [-Wother]
170 input.y:17.1-8: warning: nonterminal useless in grammar: useless8 [-Wother]
173 input.y:18.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
179 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
180 [[Nonterminals useless in grammar
190 Terminals unused in grammar
200 Rules useless in grammar
212 # Make sure the generated parser is correct.
213 AT_COMPILE([input.o])
215 AT_BISON_OPTION_POPDEFS
220 ## --------------- ##
222 ## --------------- ##
224 AT_SETUP([Useless Parts])
226 # We used to emit code that used symbol numbers before the useless
227 # symbol elimination, hence before the renumbering of the useful
228 # symbols. As a result, the evaluation of the skeleton failed because
229 # it used non existing symbol numbers. Which is the happy scenario:
230 # we could use numbers of other existing symbols...
231 # https://lists.gnu.org/r/bug-bison/2019-01/msg00044.html
233 AT_BISON_OPTION_PUSHDEFS
236 ]AT_YYERROR_DECLARE_EXTERN[
237 ]AT_YYLEX_DECLARE_EXTERN[
239 %union { void* ptr; }
257 : { $$ = YY_NULLPTR; }
261 AT_BISON_CHECK([[-fcaret -rall -o input.c input.y]], 0, [],
262 [[input.y: warning: 1 nonterminal useless in grammar [-Wother]
263 input.y: warning: 1 rule useless in grammar [-Wother]
264 input.y:18.1-6: warning: nonterminal useless in grammar: unused [-Wother]
270 AT_CHECK([[sed -n '/^State 0/q;/^$/!p' input.output]], 0,
271 [[Nonterminals useless in grammar
273 Rules useless in grammar
276 0 $accept: start $end
280 Terminals, with rules where they appear
283 Nonterminals, with rules where they appear
297 # Make sure the generated parser is correct.
298 AT_COMPILE([input.o])
300 AT_BISON_OPTION_POPDEFS
305 ## ------------------- ##
306 ## Reduced Automaton. ##
307 ## ------------------- ##
309 # Check that the automaton is that as the for the grammar reduced by
312 AT_SETUP([Reduced Automaton])
314 AT_KEYWORDS([report])
316 # The non reduced grammar.
317 # ------------------------
318 AT_DATA([[not-reduced.y]],
319 [[/* A useless token. */
324 %output "not-reduced.c"
328 exp: useful { /* A useful action. */ }
329 | non_productive { /* A non productive action. */ }
332 not_reachable: useful { /* A not reachable action. */ }
335 non_productive: non_productive useless_token
336 { /* Another non productive action. */ }
341 AT_BISON_CHECK([[-fcaret not-reduced.y]], 0, [],
342 [[not-reduced.y: warning: 2 nonterminals useless in grammar [-Wother]
343 not-reduced.y: warning: 3 rules useless in grammar [-Wother]
344 not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
345 14 | not_reachable: useful { /* A not reachable action. */ }
347 not-reduced.y:17.1-14: warning: nonterminal useless in grammar: non_productive [-Wother]
348 17 | non_productive: non_productive useless_token
350 not-reduced.y:11.6-57: warning: rule useless in grammar [-Wother]
351 11 | | non_productive { /* A non productive action. */ }
352 | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
355 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
356 [[Nonterminals useless in grammar
359 Terminals unused in grammar
361 Rules useless in grammar
362 2 exp: non_productive
363 3 not_reachable: useful
364 4 non_productive: non_productive useless_token
367 # The reduced grammar.
368 # --------------------
369 AT_DATA([[reduced.y]],
370 [[/* A useless token. */
379 exp: useful { /* A useful action. */ }
380 // | non_productive { /* A non productive action. */ } */
383 //not_reachable: useful { /* A not reachable action. */ }
386 //non_productive: non_productive useless_token
387 // { /* Another non productive action. */ }
392 AT_BISON_CHECK([[reduced.y]])
394 # Comparing the parsers.
396 AT_CHECK([sed 's/not-reduced/reduced/g' not-reduced.c], 0, [expout])
402 ## ------------------- ##
403 ## Underivable Rules. ##
404 ## ------------------- ##
406 AT_SETUP([Underivable Rules])
408 AT_KEYWORDS([report])
415 exp: useful | underivable;
416 underivable: indirection;
417 indirection: underivable;
420 AT_BISON_CHECK([[-fcaret input.y]], 0, [],
421 [[input.y: warning: 2 nonterminals useless in grammar [-Wother]
422 input.y: warning: 3 rules useless in grammar [-Wother]
423 input.y:6.1-11: warning: nonterminal useless in grammar: underivable [-Wother]
424 6 | underivable: indirection;
426 input.y:7.1-11: warning: nonterminal useless in grammar: indirection [-Wother]
427 7 | indirection: underivable;
429 input.y:5.15-25: warning: rule useless in grammar [-Wother]
430 5 | exp: useful | underivable;
434 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
435 [[Nonterminals useless in grammar
438 Rules useless in grammar
440 3 underivable: indirection
441 4 indirection: underivable
448 ## ------------------- ##
449 ## Bad start symbols. ##
450 ## ------------------- ##
452 AT_SETUP([Bad start symbols])
454 m4_pushdef([AT_TEST],
455 [AT_BISON_OPTION_PUSHDEFS([$1])
461 AT_BISON_CHECK([[input.y]], 1, [],
464 AT_BISON_OPTION_POPDEFS([$1])
469 [[input.y: warning: 2 nonterminals useless in grammar [-Wother]
470 input.y: warning: 2 rules useless in grammar [-Wother]
471 input.y:2.1-3: error: start symbol exp does not derive any sentence]])
476 [[input.y: warning: 2 nonterminals useless in grammar [-Wother]
477 input.y: warning: 2 rules useless in grammar [-Wother]
478 input.y:2.8-10: error: start symbol exp does not derive any sentence]])
484 [[input.y: warning: 1 nonterminal useless in grammar [-Wother]
485 input.y: warning: 2 rules useless in grammar [-Wother]
486 input.y:2.8-10: error: start symbol exp does not derive any sentence]])
492 [[input.y: warning: 3 nonterminals useless in grammar [-Wother]
493 input.y: warning: 4 rules useless in grammar [-Wother]
494 input.y:2.8-10: error: start symbol exp does not derive any sentence
495 input.y:2.12-15: error: start symbol stmt does not derive any sentence]])
500 [[input.y:2.8-10: warning: symbol 'exp' is used, but is not defined as a token and has no rules [-Wother]
501 input.y: warning: 3 nonterminals useless in grammar [-Wother]
502 input.y: warning: 2 rules useless in grammar [-Wother]
503 input.y:2.8-10: error: start symbol exp does not derive any sentence]])
509 [[input.y:2.8-10: error: the start symbol FOO is a token]])
517 ## ----------------- ##
518 ## %define lr.type. ##
519 ## ----------------- ##
521 # AT_TEST_LR_TYPE(DESCRIPTION,
522 # DECLS, GRAMMAR, INPUT,
523 # BISON-STDERR, TABLES,
525 # [PARSER-EXIT-VALUE],
526 # [PARSER-STDOUT], [PARSER-STDERR])
527 # -------------------------------------------------
528 m4_define([AT_TEST_LR_TYPE],
530 AT_TEST_TABLES_AND_PARSE([[no %define lr.type: ]$1],
532 [$2], m4_shiftn(2, $@))
533 AT_TEST_TABLES_AND_PARSE([[%define lr.type lalr: ]$1],
535 [[%define lr.type lalr
538 AT_TEST_TABLES_AND_PARSE([[%define lr.type ielr: ]$1],
540 [[%define lr.type ielr
543 AT_TEST_TABLES_AND_PARSE([[%define lr.type canonical-lr: ]$1],
544 [[canonical LR]], [[]],
545 [[%define lr.type canonical-lr
550 AT_TEST_LR_TYPE([[Single State Split]],
552 // Conflict resolution renders state 12 unreachable for canonical LR(1). We
553 // keep it so that the parser table diff is easier to code.
554 %define lr.keep-unreachable-state]],
556 S: 'a' A 'a' /* rule 1 */
557 | 'b' A 'b' /* rule 2 */
561 /* A conflict should appear after the first 'a' in rules 4 and 5 but only after
562 having shifted the first 'a' in rule 1. However, when LALR(1) merging is
563 chosen, the state containing that conflict is reused after having seen the
564 first 'b' in rule 2 and then the first 'a' in rules 4 and 5. In both cases,
565 because of the merged state, if the next token is an 'a', the %left forces a
566 reduction action with rule 5. In the latter case, only a shift is actually
567 grammatically correct. Thus, the parser would report a syntax error for the
568 grammatically correct sentence "baab" because it would encounter a syntax
569 error after that incorrect reduction.
571 Despite not being LALR(1), Menhir version 20070322 suffers from this problem
572 as well. It uses David Pager's weak compatibility test for merging states.
573 Bison and Menhir accept non-LR(1) grammars with conflict resolution. Pager
574 designed his algorithm only for LR(1) grammars. */
575 A: 'a' 'a' /* rule 4 */
579 /* Rule 3, rule 6, and rule 7 ensure that Bison does not report rule 4 as
580 useless after conflict resolution. This proves that, even though LALR(1)
581 generates incorrect parser tables sometimes, Bison will not necessarily
582 produce any warning to help the user realize it. */
583 c: 'a' 'b' /* rule 6 */
589 [['b', 'a', 'a', 'b']],
602 'a' shift, and go to state 1
603 'b' shift, and go to state 2
604 'c' shift, and go to state 3
615 'a' shift, and go to state 5
626 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[16]])[
639 'a' shift, and go to state 8
649 $end shift, and go to state 11
655 5 | 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
657 ]AT_COND_CASE([[canonical LR]], [['a']],
658 [[$default]])[ reduce using rule 5 (A)
660 Conflict between rule 5 and token 'a' resolved as reduce (%left 'a').
667 'a' shift, and go to state 13
674 'b' shift, and go to state 14
683 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[17]],
685 'b' shift, and go to state 15
687 ]AT_COND_CASE([[canonical LR]], [[$end]],
688 [[$default]])[ reduce using rule 5 (A)
693 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
695 ]AT_COND_CASE([[canonical LR]], [[$end]],
696 [[$default]])[ reduce using rule 7 (c)
701 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
703 ]AT_COND_CASE([[canonical LR]], [[$end]],
704 [[$default]])[ reduce using rule 3 (S)
716 4 A: 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
718 ]AT_COND_CASE([[canonical LR]], [['a']],
719 [[$default]])[ reduce using rule 4 (A)
724 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
726 ]AT_COND_CASE([[canonical LR]], [[$end]],
727 [[$default]])[ reduce using rule 1 (S)
732 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
734 ]AT_COND_CASE([[canonical LR]], [[$end]],
735 [[$default]])[ reduce using rule 2 (S)
740 6 c: 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
742 ]AT_COND_CASE([[canonical LR]], [[$end]],
743 [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]],
752 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[18]],
755 ]AT_COND_CASE([[canonical LR]], [['b']],
756 [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[
761 4 A: 'a' 'a' . [$end]
763 $end reduce using rule 4 (A)
770 'b' reduce using rule 4 (A)]])])[
776 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
777 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
779 [AT_COND_CASE([[LALR]],
783 AT_TEST_LR_TYPE([[Lane Split]],
785 // Conflict resolution renders state 16 unreachable for canonical LR(1). We
786 // keep it so that the parser table diff is easier to code.
787 %define lr.keep-unreachable-state]],
789 /* Similar to the last test case set but two states must be split. */
790 S: 'a' A 'a' /* rule 1 */
791 | 'b' A 'b' /* rule 2 */
795 A: 'a' 'a' 'a' /* rule 4 */
796 | 'a' 'a' /* rule 5 */
799 c: 'a' 'a' 'b' /* rule 6 */
805 [['b', 'a', 'a', 'a', 'b']],
818 'a' shift, and go to state 1
819 'b' shift, and go to state 2
820 'c' shift, and go to state 3
831 'a' shift, and go to state 5
842 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[18]])[
855 'a' shift, and go to state 8
865 $end shift, and go to state 11
873 'a' shift, and go to state 12
880 'a' shift, and go to state 13
887 'b' shift, and go to state 14
896 'a' shift, and go to state 15
901 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
903 ]AT_COND_CASE([[canonical LR]], [[$end]],
904 [[$default]])[ reduce using rule 7 (c)
909 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
911 ]AT_COND_CASE([[canonical LR]], [[$end]],
912 [[$default]])[ reduce using rule 3 (S)
925 5 | 'a' 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
927 ]AT_COND_CASE([[canonical LR]], [['a']],
928 [[$default]])[ reduce using rule 5 (A)
930 Conflict between rule 5 and token 'a' resolved as reduce (%left 'a').
935 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
937 ]AT_COND_CASE([[canonical LR]], [[$end]],
938 [[$default]])[ reduce using rule 1 (S)
943 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
945 ]AT_COND_CASE([[canonical LR]], [[$end]],
946 [[$default]])[ reduce using rule 2 (S)
955 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[19]],
957 'b' shift, and go to state 17
959 ]AT_COND_CASE([[canonical LR]], [[$end]],
960 [[$default]])[ reduce using rule 5 (A)
965 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
967 ]AT_COND_CASE([[canonical LR]], [['a']],
968 [[$default]])[ reduce using rule 4 (A)
973 6 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
975 ]AT_COND_CASE([[canonical LR]], [[$end]],
976 [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]],
985 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
989 State 19]AT_COND_CASE([[canonical LR]], [[
991 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
993 ]AT_COND_CASE([[canonical LR]], [[$end]],
994 [[$default]])[ reduce using rule 4 (A)
1002 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]],
1005 ]AT_COND_CASE([[canonical LR]], [['b']],
1006 [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[
1011 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['b']]])[
1013 ]AT_COND_CASE([[canonical LR]], [['b']],
1014 [[$default]])[ reduce using rule 4 (A)]])])[
1020 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
1021 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
1023 [AT_COND_CASE([[LALR]],
1027 AT_TEST_LR_TYPE([[Complex Lane Split]],
1029 // Conflict resolution renders state 16 unreachable for canonical LR(1). We
1030 // keep it so that the parser table diff is easier to code.
1031 %define lr.keep-unreachable-state]],
1033 /* Similar to the last test case set but forseeing the S/R conflict from the
1034 first state that must be split is becoming difficult. Imagine if B were
1035 even more complex. Imagine if A had other RHS's ending in other
1052 [['b', 'a', 'a', 'a', 'b']],
1065 'a' shift, and go to state 1
1066 'b' shift, and go to state 2
1067 'c' shift, and go to state 3
1077 'a' shift, and go to state 5
1087 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[19]])[
1099 'a' shift, and go to state 8
1109 $end shift, and go to state 11
1116 'a' shift, and go to state 12
1123 'a' shift, and go to state 13
1130 'b' shift, and go to state 14
1138 'a' shift, and go to state 15
1143 8 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1145 ]AT_COND_CASE([[canonical LR]], [[$end]],
1146 [[$default]])[ reduce using rule 8 (c)
1151 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1153 ]AT_COND_CASE([[canonical LR]], [[$end]],
1154 [[$default]])[ reduce using rule 3 (S)
1168 6 | %empty . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
1170 ]AT_COND_CASE([[canonical LR]], [['a']],
1171 [[$default]])[ reduce using rule 6 (B)
1175 Conflict between rule 6 and token 'a' resolved as reduce (%left 'a').
1180 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1182 ]AT_COND_CASE([[canonical LR]], [[$end]],
1183 [[$default]])[ reduce using rule 1 (S)
1188 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1190 ]AT_COND_CASE([[canonical LR]], [[$end]],
1191 [[$default]])[ reduce using rule 2 (S)
1201 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
1203 'b' shift, and go to state 18
1205 ]AT_COND_CASE([[canonical LR]], [[$end]],
1206 [[$default]])[ reduce using rule 6 (B)
1208 B go to state ]AT_COND_CASE([[canonical LR]], [[21]], [[17]])[
1213 5 B: 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
1215 ]AT_COND_CASE([[canonical LR]], [['a']],
1216 [[$default]])[ reduce using rule 5 (B)
1221 4 A: 'a' 'a' B .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
1223 ]AT_COND_CASE([[canonical LR]], [['a']],
1224 [[$default]])[ reduce using rule 4 (A)
1229 7 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1231 ]AT_COND_CASE([[canonical LR]], [[$end]],
1232 [[$default]])[ reduce using rule 7 (c)]AT_COND_CASE([[LALR]], [], [[
1239 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[22]],
1243 State 20]AT_COND_CASE([[canonical LR]], [[
1247 $end reduce using rule 5 (B)
1252 4 A: 'a' 'a' B . [$end]
1254 $end reduce using rule 4 (A)
1263 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[23]],
1266 ]AT_COND_CASE([[canonical LR]], [['b']],
1267 [[$default]])[ reduce using rule 6 (B)
1269 B go to state ]AT_COND_CASE([[canonical LR]], [[24
1276 'b' reduce using rule 5 (B)
1281 4 A: 'a' 'a' B . ['b']
1283 'b' reduce using rule 4 (A)]], [[17]])])[
1289 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
1290 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
1292 [AT_COND_CASE([[LALR]],
1296 AT_TEST_LR_TYPE([[Split During Added Lookahead Propagation]],
1297 [[%define lr.keep-unreachable-state]],
1299 /* The partial state chart diagram below is for LALR(1). State 0 is the start
1300 state. States are iterated for successor construction in numerical order.
1301 Transitions are downwards.
1303 State 13 has a R/R conflict that cannot be predicted by Bison's LR(1)
1304 algorithm using annotations alone. That is, when state 11's successor on
1305 'd' is merged with state 5 (which is originally just state 1's successor on
1306 'd'), state 5's successor on 'e' must then be changed because the resulting
1307 lookaheads that propagate to it now make it incompatible with state 8's
1308 successor on 'e'. In other words, state 13 must be split to avoid the
1326 This grammar is designed carefully to make sure that, despite Bison's LR(1)
1327 algorithm's bread-first iteration of transitions to reconstruct states,
1328 state 11's successors are constructed after state 5's and state 8's.
1329 Otherwise (for example, if you remove the first 'c' in each of rules 6 and
1330 7), state 5's successor on 'e' would never be merged with state 8's, so the
1331 split of the resulting state 13 would never need to be performed. */
1345 [['b', 'd', 'e', 'g']],
1348 [AT_COND_CASE([[LALR]],
1349 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1350 input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
1365 'a' shift, and go to state 1
1366 'b' shift, and go to state 2
1367 'c' shift, and go to state 3
1379 'd' shift, and go to state 5
1393 'd' shift, and go to state 8
1401 6 S: 'c' . 'c' A 'g'
1404 'c' shift, and go to state 11
1411 $end shift, and go to state 12
1419 'e' shift, and go to state ]AT_COND_CASE([[LALR]], [[13]],
1420 [[canonical LR]], [[13]],
1428 'f' shift, and go to state 14
1433 2 S: 'a' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1435 ]AT_COND_CASE([[canonical LR]], [[$end]],
1436 [[$default]])[ reduce using rule 2 (S)
1441 5 S: 'b' 'd' . [$end]
1445 'e' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
1448 ]AT_COND_CASE([[canonical LR]], [[$end]],
1449 [[$default]])[ reduce using rule 5 (S)
1456 'f' shift, and go to state 15
1463 'g' shift, and go to state 16
1468 6 S: 'c' 'c' . A 'g'
1473 'd' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]],
1484 $default accept]AT_COND_CASE([[LALR]], [[
1489 8 A: 'd' 'e' . ['f', 'g']
1490 9 B: 'd' 'e' . [$end, 'g']
1492 $end reduce using rule 9 (B)
1493 'g' reduce using rule 8 (A)
1494 'g' [reduce using rule 9 (B)]
1495 $default reduce using rule 8 (A)]], [[
1500 8 A: 'd' 'e' . ['f']
1501 9 B: 'd' 'e' . ]AT_COND_CASE([[canonical LR]], [[[$end]]], [[['g']]])[
1503 ]AT_COND_CASE([[canonical LR]], [[$end]],
1504 [['g' ]])[ reduce using rule 9 (B)
1505 ]AT_COND_CASE([[canonical LR]], [['f' ]],
1506 [[$default]])[ reduce using rule 8 (A)]])[
1511 1 S: 'a' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1513 ]AT_COND_CASE([[canonical LR]], [[$end]],
1514 [[$default]])[ reduce using rule 1 (S)
1519 3 S: 'b' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1521 ]AT_COND_CASE([[canonical LR]], [[$end]],
1522 [[$default]])[ reduce using rule 3 (S)
1527 4 S: 'b' B 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1529 ]AT_COND_CASE([[canonical LR]], [[$end]],
1530 [[$default]])[ reduce using rule 4 (S)
1535 6 S: 'c' 'c' A . 'g'
1537 'g' shift, and go to state 19
1542 7 S: 'c' 'c' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1544 ]AT_COND_CASE([[canonical LR]], [[$end]],
1545 [[$default]])[ reduce using rule 7 (S)
1550 6 S: 'c' 'c' A 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1552 ]AT_COND_CASE([[canonical LR]], [[$end]],
1553 [[$default]])[ reduce using rule 6 (S)]AT_COND_CASE([[LALR]],
1557 State 20]AT_COND_CASE([[canonical LR]], [[
1559 8 A: 'd' 'e' . ['f']
1560 9 B: 'd' 'e' . ['g']
1562 'f' reduce using rule 8 (A)
1563 'g' reduce using rule 9 (B)
1571 'e' shift, and go to state 22
1576 8 A: 'd' 'e' . ['g']
1577 9 B: 'd' 'e' . [$end]
1579 $end reduce using rule 9 (B)
1580 'g' reduce using rule 8 (A)]], [[
1582 8 A: 'd' 'e' . ['f', 'g']
1583 9 B: 'd' 'e' . [$end]
1585 $end reduce using rule 9 (B)
1586 $default reduce using rule 8 (A)]])])[
1592 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
1593 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
1595 [AT_COND_CASE([[LALR]],
1601 ## ------------------------------ ##
1602 ## %define lr.default-reduction. ##
1603 ## ------------------------------ ##
1605 # AT_TEST_LR_DEFAULT_REDUCTIONS(GRAMMAR, INPUT, TABLES)
1606 # -----------------------------------------------------
1607 m4_define([AT_TEST_LR_DEFAULT_REDUCTIONS],
1609 AT_TEST_TABLES_AND_PARSE([[no %define lr.default-reduction]],
1612 [$1], [$2], [[]], [$3])
1613 AT_TEST_TABLES_AND_PARSE([[%define lr.default-reduction most]],
1615 [[%define lr.default-reduction most]],
1616 [$1], [$2], [[]], [$3])
1617 AT_TEST_TABLES_AND_PARSE([[%define lr.default-reduction consistent]],
1618 [[consistent]], [[]],
1619 [[%define lr.default-reduction consistent]],
1620 [$1], [$2], [[]], [$3])
1621 AT_TEST_TABLES_AND_PARSE([[%define lr.default-reduction accepting]],
1622 [[accepting]], [[]],
1623 [[%define lr.default-reduction accepting]],
1624 [$1], [$2], [[]], [$3])
1627 AT_TEST_LR_DEFAULT_REDUCTIONS([[
1628 /* The start state is consistent and has a shift on 'a' and no reductions.
1629 After pushing the b below, enter an inconsistent state that has a shift and
1630 one reduction with one lookahead. */
1637 /* After shifting this 'a', enter a consistent state that has no shift and 1
1638 reduction with multiple lookaheads. */
1641 /* After the previous reduction, enter an inconsistent state that has no shift
1642 and multiple reductions. The first reduction has more lookaheads than the
1643 second, so the first should always be preferred as the default reduction if
1644 enabled. The second reduction has one lookahead. */
1648 dnl Visit each state mentioned above.
1652 0 $accept: . start $end
1658 'a' shift, and go to state 1
1666 4 a: 'a' .]AT_COND_CASE([[accepting]], [[ [$end, 'a', 'b']
1668 $end reduce using rule 4 (a)
1669 'a' reduce using rule 4 (a)
1670 'b' reduce using rule 4 (a)]], [[
1672 $default reduce using rule 4 (a)]])[
1677 0 $accept: start . $end
1679 $end shift, and go to state 4
1687 5 b: %empty . [$end, 'a']
1688 6 c: %empty . ['b']]AT_COND_CASE([[most]], [[
1690 'b' reduce using rule 6 (c)
1691 $default reduce using rule 5 (b)]], [[
1693 $end reduce using rule 5 (b)
1694 'a' reduce using rule 5 (b)
1695 'b' reduce using rule 6 (c)]])[
1703 0 $accept: start $end .
1710 1 start: a b . [$end]
1713 'a' shift, and go to state 7
1715 ]AT_COND_CASE([[most]], [[$default]],
1716 [[$end]])[ reduce using rule 1 (start)
1723 'b' shift, and go to state 8
1728 2 start: a b 'a' .]AT_COND_CASE([[accepting]], [[ [$end]
1730 $end reduce using rule 2 (start)]], [[
1732 $default reduce using rule 2 (start)]])[
1737 3 start: a c 'b' .]AT_COND_CASE([[accepting]], [[ [$end]
1739 $end reduce using rule 3 (start)]], [[
1741 $default reduce using rule 3 (start)]])[