1 # Exercising Bison Grammar Reduction. -*- Autotest -*-
3 # Copyright (C) 2001-2002, 2007-2012 Free Software Foundation, Inc.
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 AT_BANNER([[Grammar Reduction.]])
21 ## ------------------- ##
22 ## Useless Terminals. ##
23 ## ------------------- ##
25 AT_SETUP([Useless Terminals])
46 AT_BISON_CHECK([[input.y]])
48 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
49 [[Terminals unused in grammar
65 ## ---------------------- ##
66 ## Useless Nonterminals. ##
67 ## ---------------------- ##
69 AT_SETUP([Useless Nonterminals])
90 AT_BISON_CHECK([[input.y]], 0, [],
91 [[input.y: warning: 9 nonterminals useless in grammar [-Wother]
92 input.y:4.8-15: warning: nonterminal useless in grammar: useless1 [-Wother]
93 input.y:5.8-15: warning: nonterminal useless in grammar: useless2 [-Wother]
94 input.y:6.8-15: warning: nonterminal useless in grammar: useless3 [-Wother]
95 input.y:7.8-15: warning: nonterminal useless in grammar: useless4 [-Wother]
96 input.y:8.8-15: warning: nonterminal useless in grammar: useless5 [-Wother]
97 input.y:9.8-15: warning: nonterminal useless in grammar: useless6 [-Wother]
98 input.y:10.8-15: warning: nonterminal useless in grammar: useless7 [-Wother]
99 input.y:11.8-15: warning: nonterminal useless in grammar: useless8 [-Wother]
100 input.y:12.8-15: warning: nonterminal useless in grammar: useless9 [-Wother]
103 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
104 [[Nonterminals useless in grammar
120 ## --------------- ##
122 ## --------------- ##
124 AT_SETUP([Useless Rules])
126 AT_KEYWORDS([report])
145 AT_BISON_CHECK([[-fcaret input.y]], 0, [],
146 [[input.y: warning: 9 nonterminals useless in grammar [-Wother]
147 input.y: warning: 9 rules useless in grammar [-Wother]
148 input.y:6.1-8: warning: nonterminal useless in grammar: useless1 [-Wother]
151 input.y:7.1-8: warning: nonterminal useless in grammar: useless2 [-Wother]
154 input.y:8.1-8: warning: nonterminal useless in grammar: useless3 [-Wother]
157 input.y:9.1-8: warning: nonterminal useless in grammar: useless4 [-Wother]
160 input.y:10.1-8: warning: nonterminal useless in grammar: useless5 [-Wother]
163 input.y:11.1-8: warning: nonterminal useless in grammar: useless6 [-Wother]
166 input.y:12.1-8: warning: nonterminal useless in grammar: useless7 [-Wother]
169 input.y:13.1-8: warning: nonterminal useless in grammar: useless8 [-Wother]
172 input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
175 input.y:6.11-13: warning: rule useless in grammar [-Wother]
178 input.y:7.11-13: warning: rule useless in grammar [-Wother]
181 input.y:8.11-13: warning: rule useless in grammar [-Wother]
184 input.y:9.11-13: warning: rule useless in grammar [-Wother]
187 input.y:10.11-13: warning: rule useless in grammar [-Wother]
190 input.y:11.11-13: warning: rule useless in grammar [-Wother]
193 input.y:12.11-13: warning: rule useless in grammar [-Wother]
196 input.y:13.11-13: warning: rule useless in grammar [-Wother]
199 input.y:14.11-13: warning: rule useless in grammar [-Wother]
204 AT_BISON_CHECK([[input.y]], 0, [],
205 [[input.y: warning: 9 nonterminals useless in grammar [-Wother]
206 input.y: warning: 9 rules useless in grammar [-Wother]
207 input.y:6.1-8: warning: nonterminal useless in grammar: useless1 [-Wother]
208 input.y:7.1-8: warning: nonterminal useless in grammar: useless2 [-Wother]
209 input.y:8.1-8: warning: nonterminal useless in grammar: useless3 [-Wother]
210 input.y:9.1-8: warning: nonterminal useless in grammar: useless4 [-Wother]
211 input.y:10.1-8: warning: nonterminal useless in grammar: useless5 [-Wother]
212 input.y:11.1-8: warning: nonterminal useless in grammar: useless6 [-Wother]
213 input.y:12.1-8: warning: nonterminal useless in grammar: useless7 [-Wother]
214 input.y:13.1-8: warning: nonterminal useless in grammar: useless8 [-Wother]
215 input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
216 input.y:6.11-13: warning: rule useless in grammar: useless1: '1' [-Wother]
217 input.y:7.11-13: warning: rule useless in grammar: useless2: '2' [-Wother]
218 input.y:8.11-13: warning: rule useless in grammar: useless3: '3' [-Wother]
219 input.y:9.11-13: warning: rule useless in grammar: useless4: '4' [-Wother]
220 input.y:10.11-13: warning: rule useless in grammar: useless5: '5' [-Wother]
221 input.y:11.11-13: warning: rule useless in grammar: useless6: '6' [-Wother]
222 input.y:12.11-13: warning: rule useless in grammar: useless7: '7' [-Wother]
223 input.y:13.11-13: warning: rule useless in grammar: useless8: '8' [-Wother]
224 input.y:14.11-13: warning: rule useless in grammar: useless9: '9' [-Wother]
227 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
228 [[Nonterminals useless in grammar
238 Terminals unused in grammar
248 Rules useless in grammar
264 ## ------------------- ##
265 ## Reduced Automaton. ##
266 ## ------------------- ##
268 # Check that the automaton is that as the for the grammar reduced by
271 AT_SETUP([Reduced Automaton])
273 AT_KEYWORDS([report])
275 # The non reduced grammar.
276 # ------------------------
277 AT_DATA([[not-reduced.y]],
278 [[/* A useless token. */
283 %output "not-reduced.c"
287 exp: useful { /* A useful action. */ }
288 | non_productive { /* A non productive action. */ }
291 not_reachable: useful { /* A not reachable action. */ }
294 non_productive: non_productive useless_token
295 { /* Another non productive action. */ }
300 AT_BISON_CHECK([[-fcaret not-reduced.y]], 0, [],
301 [[not-reduced.y: warning: 2 nonterminals useless in grammar [-Wother]
302 not-reduced.y: warning: 3 rules useless in grammar [-Wother]
303 not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
304 not_reachable: useful { /* A not reachable action. */ }
306 not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive [-Wother]
307 | non_productive { /* A non productive action. */ }
309 not-reduced.y:11.6-57: warning: rule useless in grammar [-Wother]
310 | non_productive { /* A non productive action. */ }
311 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
312 not-reduced.y:14.16-56: warning: rule useless in grammar [-Wother]
313 not_reachable: useful { /* A not reachable action. */ }
314 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
315 not-reduced.y:17.17-18.63: warning: rule useless in grammar [-Wother]
316 non_productive: non_productive useless_token
317 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
320 AT_BISON_CHECK([[not-reduced.y]], 0, [],
321 [[not-reduced.y: warning: 2 nonterminals useless in grammar [-Wother]
322 not-reduced.y: warning: 3 rules useless in grammar [-Wother]
323 not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
324 not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive [-Wother]
325 not-reduced.y:11.6-57: warning: rule useless in grammar: exp: non_productive [-Wother]
326 not-reduced.y:14.16-56: warning: rule useless in grammar: not_reachable: useful [-Wother]
327 not-reduced.y:17.17-18.63: warning: rule useless in grammar: non_productive: non_productive useless_token [-Wother]
330 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
331 [[Nonterminals useless in grammar
334 Terminals unused in grammar
336 Rules useless in grammar
337 2 exp: non_productive
338 3 not_reachable: useful
339 4 non_productive: non_productive useless_token
342 # The reduced grammar.
343 # --------------------
344 AT_DATA([[reduced.y]],
345 [[/* A useless token. */
354 exp: useful { /* A useful action. */ }
355 // | non_productive { /* A non productive action. */ } */
358 //not_reachable: useful { /* A not reachable action. */ }
361 //non_productive: non_productive useless_token
362 // { /* Another non productive action. */ }
367 AT_BISON_CHECK([[reduced.y]])
369 # Comparing the parsers.
371 AT_CHECK([sed 's/not-reduced/reduced/g' not-reduced.c], 0, [expout])
377 ## ------------------- ##
378 ## Underivable Rules. ##
379 ## ------------------- ##
381 AT_SETUP([Underivable Rules])
383 AT_KEYWORDS([report])
390 exp: useful | underivable;
391 underivable: indirection;
392 indirection: underivable;
395 AT_BISON_CHECK([[input.y]], 0, [],
396 [[input.y: warning: 2 nonterminals useless in grammar [-Wother]
397 input.y: warning: 3 rules useless in grammar [-Wother]
398 input.y:5.15-25: warning: nonterminal useless in grammar: underivable [-Wother]
399 input.y:6.14-24: warning: nonterminal useless in grammar: indirection [-Wother]
400 input.y:5.15-25: warning: rule useless in grammar: exp: underivable [-Wother]
401 input.y:6.14-24: warning: rule useless in grammar: underivable: indirection [-Wother]
402 input.y:7.14-24: warning: rule useless in grammar: indirection: underivable [-Wother]
405 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
406 [[Nonterminals useless in grammar
409 Rules useless in grammar
411 3 underivable: indirection
412 4 indirection: underivable
419 ## ---------------- ##
420 ## Empty Language. ##
421 ## ---------------- ##
423 AT_SETUP([Empty Language])
431 AT_BISON_CHECK([[input.y]], 1, [],
432 [[input.y: warning: 2 nonterminals useless in grammar [-Wother]
433 input.y: warning: 2 rules useless in grammar [-Wother]
434 input.y:3.1-3: fatal error: start symbol exp does not derive any sentence
441 ## ----------------- ##
442 ## %define lr.type. ##
443 ## ----------------- ##
445 # AT_TEST_LR_TYPE(DESCRIPTION,
446 # DECLS, GRAMMAR, INPUT,
447 # BISON-STDERR, TABLES,
449 # [PARSER-EXIT-VALUE],
450 # [PARSER-STDOUT], [PARSER-STDERR])
451 # -------------------------------------------------
452 m4_define([AT_TEST_LR_TYPE],
454 AT_TEST_TABLES_AND_PARSE([[no %define lr.type: ]$1],
456 [$2], m4_shiftn(2, $@))
457 AT_TEST_TABLES_AND_PARSE([[%define lr.type lalr: ]$1],
459 [[%define lr.type lalr
462 AT_TEST_TABLES_AND_PARSE([[%define lr.type ielr: ]$1],
464 [[%define lr.type ielr
467 AT_TEST_TABLES_AND_PARSE([[%define lr.type canonical-lr: ]$1],
468 [[canonical LR]], [[]],
469 [[%define lr.type canonical-lr
474 AT_TEST_LR_TYPE([[Single State Split]],
476 // Conflict resolution renders state 12 unreachable for canonical LR(1). We
477 // keep it so that the paser table diff is easier to code.
478 %define lr.keep-unreachable-state]],
480 S: 'a' A 'a' /* rule 1 */
481 | 'b' A 'b' /* rule 2 */
485 /* A conflict should appear after the first 'a' in rules 4 and 5 but only after
486 having shifted the first 'a' in rule 1. However, when LALR(1) merging is
487 chosen, the state containing that conflict is reused after having seen the
488 first 'b' in rule 2 and then the first 'a' in rules 4 and 5. In both cases,
489 because of the merged state, if the next token is an 'a', the %left forces a
490 reduction action with rule 5. In the latter case, only a shift is actually
491 grammatically correct. Thus, the parser would report a syntax error for the
492 grammatically correct sentence "baab" because it would encounter a syntax
493 error after that incorrect reduction.
495 Despite not being LALR(1), Menhir version 20070322 suffers from this problem
496 as well. It uses David Pager's weak compatibility test for merging states.
497 Bison and Menhir accept non-LR(1) grammars with conflict resolution. Pager
498 designed his algorithm only for LR(1) grammars. */
499 A: 'a' 'a' /* rule 4 */
503 /* Rule 3, rule 6, and rule 7 ensure that Bison does not report rule 4 as
504 useless after conflict resolution. This proves that, even though LALR(1)
505 generates incorrect parser tables sometimes, Bison will not necessarily
506 produce any warning to help the user realize it. */
507 c: 'a' 'b' /* rule 6 */
513 [['b', 'a', 'a', 'b']],
526 'a' shift, and go to state 1
527 'b' shift, and go to state 2
528 'c' shift, and go to state 3
539 'a' shift, and go to state 5
550 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[16]])[
563 'a' shift, and go to state 8
573 $end shift, and go to state 11
579 5 | 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
581 ]AT_COND_CASE([[canonical LR]], [['a']],
582 [[$default]])[ reduce using rule 5 (A)
584 Conflict between rule 5 and token 'a' resolved as reduce (%left 'a').
591 'a' shift, and go to state 13
598 'b' shift, and go to state 14
607 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[17]],
609 'b' shift, and go to state 15
611 ]AT_COND_CASE([[canonical LR]], [[$end]],
612 [[$default]])[ reduce using rule 5 (A)
617 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
619 ]AT_COND_CASE([[canonical LR]], [[$end]],
620 [[$default]])[ reduce using rule 7 (c)
625 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
627 ]AT_COND_CASE([[canonical LR]], [[$end]],
628 [[$default]])[ reduce using rule 3 (S)
640 4 A: 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
642 ]AT_COND_CASE([[canonical LR]], [['a']],
643 [[$default]])[ reduce using rule 4 (A)
648 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
650 ]AT_COND_CASE([[canonical LR]], [[$end]],
651 [[$default]])[ reduce using rule 1 (S)
656 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
658 ]AT_COND_CASE([[canonical LR]], [[$end]],
659 [[$default]])[ reduce using rule 2 (S)
664 6 c: 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
666 ]AT_COND_CASE([[canonical LR]], [[$end]],
667 [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]],
676 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[18]],
679 ]AT_COND_CASE([[canonical LR]], [['b']],
680 [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[
685 4 A: 'a' 'a' . [$end]
687 $end reduce using rule 4 (A)
694 'b' reduce using rule 4 (A)]])])[
700 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
701 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
703 [AT_COND_CASE([[LALR]],
707 AT_TEST_LR_TYPE([[Lane Split]],
709 // Conflict resolution renders state 16 unreachable for canonical LR(1). We
710 // keep it so that the paser table diff is easier to code.
711 %define lr.keep-unreachable-state]],
713 /* Similar to the last test case set but two states must be split. */
714 S: 'a' A 'a' /* rule 1 */
715 | 'b' A 'b' /* rule 2 */
719 A: 'a' 'a' 'a' /* rule 4 */
720 | 'a' 'a' /* rule 5 */
723 c: 'a' 'a' 'b' /* rule 6 */
729 [['b', 'a', 'a', 'a', 'b']],
742 'a' shift, and go to state 1
743 'b' shift, and go to state 2
744 'c' shift, and go to state 3
755 'a' shift, and go to state 5
766 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[18]])[
779 'a' shift, and go to state 8
789 $end shift, and go to state 11
797 'a' shift, and go to state 12
804 'a' shift, and go to state 13
811 'b' shift, and go to state 14
820 'a' shift, and go to state 15
825 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
827 ]AT_COND_CASE([[canonical LR]], [[$end]],
828 [[$default]])[ reduce using rule 7 (c)
833 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
835 ]AT_COND_CASE([[canonical LR]], [[$end]],
836 [[$default]])[ reduce using rule 3 (S)
849 5 | 'a' 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
851 ]AT_COND_CASE([[canonical LR]], [['a']],
852 [[$default]])[ reduce using rule 5 (A)
854 Conflict between rule 5 and token 'a' resolved as reduce (%left 'a').
859 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
861 ]AT_COND_CASE([[canonical LR]], [[$end]],
862 [[$default]])[ reduce using rule 1 (S)
867 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
869 ]AT_COND_CASE([[canonical LR]], [[$end]],
870 [[$default]])[ reduce using rule 2 (S)
879 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[19]],
881 'b' shift, and go to state 17
883 ]AT_COND_CASE([[canonical LR]], [[$end]],
884 [[$default]])[ reduce using rule 5 (A)
889 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
891 ]AT_COND_CASE([[canonical LR]], [['a']],
892 [[$default]])[ reduce using rule 4 (A)
897 6 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
899 ]AT_COND_CASE([[canonical LR]], [[$end]],
900 [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]],
909 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
913 State 19]AT_COND_CASE([[canonical LR]], [[
915 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
917 ]AT_COND_CASE([[canonical LR]], [[$end]],
918 [[$default]])[ reduce using rule 4 (A)
926 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]],
929 ]AT_COND_CASE([[canonical LR]], [['b']],
930 [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[
935 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['b']]])[
937 ]AT_COND_CASE([[canonical LR]], [['b']],
938 [[$default]])[ reduce using rule 4 (A)]])])[
944 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
945 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
947 [AT_COND_CASE([[LALR]],
951 AT_TEST_LR_TYPE([[Complex Lane Split]],
953 // Conflict resolution renders state 16 unreachable for canonical LR(1). We
954 // keep it so that the paser table diff is easier to code.
955 %define lr.keep-unreachable-state]],
957 /* Similar to the last test case set but forseeing the S/R conflict from the
958 first state that must be split is becoming difficult. Imagine if B were
959 even more complex. Imagine if A had other RHS's ending in other
976 [['b', 'a', 'a', 'a', 'b']],
989 'a' shift, and go to state 1
990 'b' shift, and go to state 2
991 'c' shift, and go to state 3
1001 'a' shift, and go to state 5
1011 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[19]])[
1023 'a' shift, and go to state 8
1033 $end shift, and go to state 11
1040 'a' shift, and go to state 12
1047 'a' shift, and go to state 13
1054 'b' shift, and go to state 14
1062 'a' shift, and go to state 15
1067 8 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1069 ]AT_COND_CASE([[canonical LR]], [[$end]],
1070 [[$default]])[ reduce using rule 8 (c)
1075 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1077 ]AT_COND_CASE([[canonical LR]], [[$end]],
1078 [[$default]])[ reduce using rule 3 (S)
1092 6 | . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
1094 ]AT_COND_CASE([[canonical LR]], [['a']],
1095 [[$default]])[ reduce using rule 6 (B)
1099 Conflict between rule 6 and token 'a' resolved as reduce (%left 'a').
1104 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1106 ]AT_COND_CASE([[canonical LR]], [[$end]],
1107 [[$default]])[ reduce using rule 1 (S)
1112 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1114 ]AT_COND_CASE([[canonical LR]], [[$end]],
1115 [[$default]])[ reduce using rule 2 (S)
1125 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
1127 'b' shift, and go to state 18
1129 ]AT_COND_CASE([[canonical LR]], [[$end]],
1130 [[$default]])[ reduce using rule 6 (B)
1132 B go to state ]AT_COND_CASE([[canonical LR]], [[21]], [[17]])[
1137 5 B: 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
1139 ]AT_COND_CASE([[canonical LR]], [['a']],
1140 [[$default]])[ reduce using rule 5 (B)
1145 4 A: 'a' 'a' B .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
1147 ]AT_COND_CASE([[canonical LR]], [['a']],
1148 [[$default]])[ reduce using rule 4 (A)
1153 7 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1155 ]AT_COND_CASE([[canonical LR]], [[$end]],
1156 [[$default]])[ reduce using rule 7 (c)]AT_COND_CASE([[LALR]], [], [[
1163 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[22]],
1167 State 20]AT_COND_CASE([[canonical LR]], [[
1171 $end reduce using rule 5 (B)
1176 4 A: 'a' 'a' B . [$end]
1178 $end reduce using rule 4 (A)
1187 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[23]],
1190 ]AT_COND_CASE([[canonical LR]], [['b']],
1191 [[$default]])[ reduce using rule 6 (B)
1193 B go to state ]AT_COND_CASE([[canonical LR]], [[24
1200 'b' reduce using rule 5 (B)
1205 4 A: 'a' 'a' B . ['b']
1207 'b' reduce using rule 4 (A)]], [[17]])])[
1213 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
1214 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
1216 [AT_COND_CASE([[LALR]],
1220 AT_TEST_LR_TYPE([[Split During Added Lookahead Propagation]],
1221 [[%define lr.keep-unreachable-state]],
1223 /* The partial state chart diagram below is for LALR(1). State 0 is the start
1224 state. States are iterated for successor construction in numerical order.
1225 Transitions are downwards.
1227 State 13 has a R/R conflict that cannot be predicted by Bison's LR(1)
1228 algorithm using annotations alone. That is, when state 11's successor on
1229 'd' is merged with state 5 (which is originally just state 1's successor on
1230 'd'), state 5's successor on 'e' must then be changed because the resulting
1231 lookaheads that propagate to it now make it incompatible with state 8's
1232 successor on 'e'. In other words, state 13 must be split to avoid the
1250 This grammar is designed carefully to make sure that, despite Bison's LR(1)
1251 algorithm's bread-first iteration of transitions to reconstruct states,
1252 state 11's successors are constructed after state 5's and state 8's.
1253 Otherwise (for example, if you remove the first 'c' in each of rules 6 and
1254 7), state 5's successor on 'e' would never be merged with state 8's, so the
1255 split of the resulting state 13 would never need to be performed. */
1269 [['b', 'd', 'e', 'g']],
1272 [AT_COND_CASE([[LALR]],
1273 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1288 'a' shift, and go to state 1
1289 'b' shift, and go to state 2
1290 'c' shift, and go to state 3
1302 'd' shift, and go to state 5
1316 'd' shift, and go to state 8
1324 6 S: 'c' . 'c' A 'g'
1327 'c' shift, and go to state 11
1334 $end shift, and go to state 12
1342 'e' shift, and go to state ]AT_COND_CASE([[LALR]], [[13]],
1343 [[canonical LR]], [[13]],
1351 'f' shift, and go to state 14
1356 2 S: 'a' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1358 ]AT_COND_CASE([[canonical LR]], [[$end]],
1359 [[$default]])[ reduce using rule 2 (S)
1364 5 S: 'b' 'd' . [$end]
1368 'e' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
1371 ]AT_COND_CASE([[canonical LR]], [[$end]],
1372 [[$default]])[ reduce using rule 5 (S)
1379 'f' shift, and go to state 15
1386 'g' shift, and go to state 16
1391 6 S: 'c' 'c' . A 'g'
1396 'd' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]],
1407 $default accept]AT_COND_CASE([[LALR]], [[
1412 8 A: 'd' 'e' . ['f', 'g']
1413 9 B: 'd' 'e' . [$end, 'g']
1415 $end reduce using rule 9 (B)
1416 'g' reduce using rule 8 (A)
1417 'g' [reduce using rule 9 (B)]
1418 $default reduce using rule 8 (A)]], [[
1423 8 A: 'd' 'e' . ['f']
1424 9 B: 'd' 'e' . ]AT_COND_CASE([[canonical LR]], [[[$end]]], [[['g']]])[
1426 ]AT_COND_CASE([[canonical LR]], [[$end]],
1427 [['g' ]])[ reduce using rule 9 (B)
1428 ]AT_COND_CASE([[canonical LR]], [['f' ]],
1429 [[$default]])[ reduce using rule 8 (A)]])[
1434 1 S: 'a' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1436 ]AT_COND_CASE([[canonical LR]], [[$end]],
1437 [[$default]])[ reduce using rule 1 (S)
1442 3 S: 'b' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1444 ]AT_COND_CASE([[canonical LR]], [[$end]],
1445 [[$default]])[ reduce using rule 3 (S)
1450 4 S: 'b' B 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1452 ]AT_COND_CASE([[canonical LR]], [[$end]],
1453 [[$default]])[ reduce using rule 4 (S)
1458 6 S: 'c' 'c' A . 'g'
1460 'g' shift, and go to state 19
1465 7 S: 'c' 'c' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1467 ]AT_COND_CASE([[canonical LR]], [[$end]],
1468 [[$default]])[ reduce using rule 7 (S)
1473 6 S: 'c' 'c' A 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1475 ]AT_COND_CASE([[canonical LR]], [[$end]],
1476 [[$default]])[ reduce using rule 6 (S)]AT_COND_CASE([[LALR]],
1480 State 20]AT_COND_CASE([[canonical LR]], [[
1482 8 A: 'd' 'e' . ['f']
1483 9 B: 'd' 'e' . ['g']
1485 'f' reduce using rule 8 (A)
1486 'g' reduce using rule 9 (B)
1494 'e' shift, and go to state 22
1499 8 A: 'd' 'e' . ['g']
1500 9 B: 'd' 'e' . [$end]
1502 $end reduce using rule 9 (B)
1503 'g' reduce using rule 8 (A)]], [[
1505 8 A: 'd' 'e' . ['f', 'g']
1506 9 B: 'd' 'e' . [$end]
1508 $end reduce using rule 9 (B)
1509 $default reduce using rule 8 (A)]])])[
1515 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
1516 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
1518 [AT_COND_CASE([[LALR]],
1524 ## ------------------------------- ##
1525 ## %define lr.default-reduction. ##
1526 ## ------------------------------- ##
1528 # AT_TEST_LR_DEFAULT_REDUCTIONS(GRAMMAR, INPUT, TABLES)
1529 # -----------------------------------------------------
1530 m4_define([AT_TEST_LR_DEFAULT_REDUCTIONS],
1532 AT_TEST_TABLES_AND_PARSE([[no %define lr.default-reduction]],
1535 [$1], [$2], [[]], [$3])
1536 AT_TEST_TABLES_AND_PARSE([[%define lr.default-reduction most]],
1538 [[%define lr.default-reduction most]],
1539 [$1], [$2], [[]], [$3])
1540 AT_TEST_TABLES_AND_PARSE([[%define lr.default-reduction consistent]],
1541 [[consistent]], [[]],
1542 [[%define lr.default-reduction consistent]],
1543 [$1], [$2], [[]], [$3])
1544 AT_TEST_TABLES_AND_PARSE([[%define lr.default-reduction accepting]],
1545 [[accepting]], [[]],
1546 [[%define lr.default-reduction accepting]],
1547 [$1], [$2], [[]], [$3])
1550 AT_TEST_LR_DEFAULT_REDUCTIONS([[
1551 /* The start state is consistent and has a shift on 'a' and no reductions.
1552 After pushing the b below, enter an inconsistent state that has a shift and
1553 one reduction with one lookahead. */
1560 /* After shifting this 'a', enter a consistent state that has no shift and 1
1561 reduction with multiple lookaheads. */
1564 /* After the previous reduction, enter an inconsistent state that has no shift
1565 and multiple reductions. The first reduction has more lookaheads than the
1566 second, so the first should always be preferred as the default reduction if
1567 enabled. The second reduction has one lookahead. */
1571 dnl Visit each state mentioned above.
1575 0 $accept: . start $end
1581 'a' shift, and go to state 1
1589 4 a: 'a' .]AT_COND_CASE([[accepting]], [[ [$end, 'a', 'b']
1591 $end reduce using rule 4 (a)
1592 'a' reduce using rule 4 (a)
1593 'b' reduce using rule 4 (a)]], [[
1595 $default reduce using rule 4 (a)]])[
1600 0 $accept: start . $end
1602 $end shift, and go to state 4
1611 6 c: . ['b']]AT_COND_CASE([[most]], [[
1613 'b' reduce using rule 6 (c)
1614 $default reduce using rule 5 (b)]], [[
1616 $end reduce using rule 5 (b)
1617 'a' reduce using rule 5 (b)
1618 'b' reduce using rule 6 (c)]])[
1626 0 $accept: start $end .
1633 1 start: a b . [$end]
1636 'a' shift, and go to state 7
1638 ]AT_COND_CASE([[most]], [[$default]],
1639 [[$end]])[ reduce using rule 1 (start)
1646 'b' shift, and go to state 8
1651 2 start: a b 'a' .]AT_COND_CASE([[accepting]], [[ [$end]
1653 $end reduce using rule 2 (start)]], [[
1655 $default reduce using rule 2 (start)]])[
1660 3 start: a c 'b' .]AT_COND_CASE([[accepting]], [[ [$end]
1662 $end reduce using rule 3 (start)]], [[
1664 $default reduce using rule 3 (start)]])[