1 # Exercising Bison Grammar Reduction. -*- Autotest -*-
3 # Copyright (C) 2001-2002, 2007-2013 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]
205 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
206 [[Nonterminals useless in grammar
216 Terminals unused in grammar
226 Rules useless in grammar
242 ## ------------------- ##
243 ## Reduced Automaton. ##
244 ## ------------------- ##
246 # Check that the automaton is that as the for the grammar reduced by
249 AT_SETUP([Reduced Automaton])
251 AT_KEYWORDS([report])
253 # The non reduced grammar.
254 # ------------------------
255 AT_DATA([[not-reduced.y]],
256 [[/* A useless token. */
261 %output "not-reduced.c"
265 exp: useful { /* A useful action. */ }
266 | non_productive { /* A non productive action. */ }
269 not_reachable: useful { /* A not reachable action. */ }
272 non_productive: non_productive useless_token
273 { /* Another non productive action. */ }
278 AT_BISON_CHECK([[-fcaret not-reduced.y]], 0, [],
279 [[not-reduced.y: warning: 2 nonterminals useless in grammar [-Wother]
280 not-reduced.y: warning: 3 rules useless in grammar [-Wother]
281 not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
282 not_reachable: useful { /* A not reachable action. */ }
284 not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive [-Wother]
285 | non_productive { /* A non productive action. */ }
287 not-reduced.y:11.6-57: warning: rule useless in grammar [-Wother]
288 | non_productive { /* A non productive action. */ }
289 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
290 not-reduced.y:14.16-56: warning: rule useless in grammar [-Wother]
291 not_reachable: useful { /* A not reachable action. */ }
292 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
293 not-reduced.y:17.17-18.63: warning: rule useless in grammar [-Wother]
294 non_productive: non_productive useless_token
295 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
298 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
299 [[Nonterminals useless in grammar
302 Terminals unused in grammar
304 Rules useless in grammar
305 2 exp: non_productive
306 3 not_reachable: useful
307 4 non_productive: non_productive useless_token
310 # The reduced grammar.
311 # --------------------
312 AT_DATA([[reduced.y]],
313 [[/* A useless token. */
322 exp: useful { /* A useful action. */ }
323 // | non_productive { /* A non productive action. */ } */
326 //not_reachable: useful { /* A not reachable action. */ }
329 //non_productive: non_productive useless_token
330 // { /* Another non productive action. */ }
335 AT_BISON_CHECK([[reduced.y]])
337 # Comparing the parsers.
339 AT_CHECK([sed 's/not-reduced/reduced/g' not-reduced.c], 0, [expout])
345 ## ------------------- ##
346 ## Underivable Rules. ##
347 ## ------------------- ##
349 AT_SETUP([Underivable Rules])
351 AT_KEYWORDS([report])
358 exp: useful | underivable;
359 underivable: indirection;
360 indirection: underivable;
363 AT_BISON_CHECK([[input.y]], 0, [],
364 [[input.y: warning: 2 nonterminals useless in grammar [-Wother]
365 input.y: warning: 3 rules useless in grammar [-Wother]
366 input.y:5.15-25: warning: nonterminal useless in grammar: underivable [-Wother]
367 input.y:6.14-24: warning: nonterminal useless in grammar: indirection [-Wother]
368 input.y:5.15-25: warning: rule useless in grammar [-Wother]
369 input.y:6.14-24: warning: rule useless in grammar [-Wother]
370 input.y:7.14-24: warning: rule useless in grammar [-Wother]
373 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
374 [[Nonterminals useless in grammar
377 Rules useless in grammar
379 3 underivable: indirection
380 4 indirection: underivable
387 ## ---------------- ##
388 ## Empty Language. ##
389 ## ---------------- ##
391 AT_SETUP([Empty Language])
399 AT_BISON_CHECK([[input.y]], 1, [],
400 [[input.y: warning: 2 nonterminals useless in grammar [-Wother]
401 input.y: warning: 2 rules useless in grammar [-Wother]
402 input.y:3.1-3: fatal error: start symbol exp does not derive any sentence
409 ## ----------------- ##
410 ## %define lr.type. ##
411 ## ----------------- ##
413 # AT_TEST_LR_TYPE(DESCRIPTION,
414 # DECLS, GRAMMAR, INPUT,
415 # BISON-STDERR, TABLES,
417 # [PARSER-EXIT-VALUE],
418 # [PARSER-STDOUT], [PARSER-STDERR])
419 # -------------------------------------------------
420 m4_define([AT_TEST_LR_TYPE],
422 AT_TEST_TABLES_AND_PARSE([[no %define lr.type: ]$1],
424 [$2], m4_shiftn(2, $@))
425 AT_TEST_TABLES_AND_PARSE([[%define lr.type lalr: ]$1],
427 [[%define lr.type lalr
430 AT_TEST_TABLES_AND_PARSE([[%define lr.type ielr: ]$1],
432 [[%define lr.type ielr
435 AT_TEST_TABLES_AND_PARSE([[%define lr.type canonical-lr: ]$1],
436 [[canonical LR]], [[]],
437 [[%define lr.type canonical-lr
442 AT_TEST_LR_TYPE([[Single State Split]],
444 // Conflict resolution renders state 12 unreachable for canonical LR(1). We
445 // keep it so that the paser table diff is easier to code.
446 %define lr.keep-unreachable-state]],
448 S: 'a' A 'a' /* rule 1 */
449 | 'b' A 'b' /* rule 2 */
453 /* A conflict should appear after the first 'a' in rules 4 and 5 but only after
454 having shifted the first 'a' in rule 1. However, when LALR(1) merging is
455 chosen, the state containing that conflict is reused after having seen the
456 first 'b' in rule 2 and then the first 'a' in rules 4 and 5. In both cases,
457 because of the merged state, if the next token is an 'a', the %left forces a
458 reduction action with rule 5. In the latter case, only a shift is actually
459 grammatically correct. Thus, the parser would report a syntax error for the
460 grammatically correct sentence "baab" because it would encounter a syntax
461 error after that incorrect reduction.
463 Despite not being LALR(1), Menhir version 20070322 suffers from this problem
464 as well. It uses David Pager's weak compatibility test for merging states.
465 Bison and Menhir accept non-LR(1) grammars with conflict resolution. Pager
466 designed his algorithm only for LR(1) grammars. */
467 A: 'a' 'a' /* rule 4 */
471 /* Rule 3, rule 6, and rule 7 ensure that Bison does not report rule 4 as
472 useless after conflict resolution. This proves that, even though LALR(1)
473 generates incorrect parser tables sometimes, Bison will not necessarily
474 produce any warning to help the user realize it. */
475 c: 'a' 'b' /* rule 6 */
481 [['b', 'a', 'a', 'b']],
494 'a' shift, and go to state 1
495 'b' shift, and go to state 2
496 'c' shift, and go to state 3
507 'a' shift, and go to state 5
518 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[16]])[
531 'a' shift, and go to state 8
541 $end shift, and go to state 11
547 5 | 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
549 ]AT_COND_CASE([[canonical LR]], [['a']],
550 [[$default]])[ reduce using rule 5 (A)
552 Conflict between rule 5 and token 'a' resolved as reduce (%left 'a').
559 'a' shift, and go to state 13
566 'b' shift, and go to state 14
575 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[17]],
577 'b' shift, and go to state 15
579 ]AT_COND_CASE([[canonical LR]], [[$end]],
580 [[$default]])[ reduce using rule 5 (A)
585 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
587 ]AT_COND_CASE([[canonical LR]], [[$end]],
588 [[$default]])[ reduce using rule 7 (c)
593 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
595 ]AT_COND_CASE([[canonical LR]], [[$end]],
596 [[$default]])[ reduce using rule 3 (S)
608 4 A: 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
610 ]AT_COND_CASE([[canonical LR]], [['a']],
611 [[$default]])[ reduce using rule 4 (A)
616 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
618 ]AT_COND_CASE([[canonical LR]], [[$end]],
619 [[$default]])[ reduce using rule 1 (S)
624 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
626 ]AT_COND_CASE([[canonical LR]], [[$end]],
627 [[$default]])[ reduce using rule 2 (S)
632 6 c: 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
634 ]AT_COND_CASE([[canonical LR]], [[$end]],
635 [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]],
644 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[18]],
647 ]AT_COND_CASE([[canonical LR]], [['b']],
648 [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[
653 4 A: 'a' 'a' . [$end]
655 $end reduce using rule 4 (A)
662 'b' reduce using rule 4 (A)]])])[
668 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
669 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
671 [AT_COND_CASE([[LALR]],
675 AT_TEST_LR_TYPE([[Lane Split]],
677 // Conflict resolution renders state 16 unreachable for canonical LR(1). We
678 // keep it so that the paser table diff is easier to code.
679 %define lr.keep-unreachable-state]],
681 /* Similar to the last test case set but two states must be split. */
682 S: 'a' A 'a' /* rule 1 */
683 | 'b' A 'b' /* rule 2 */
687 A: 'a' 'a' 'a' /* rule 4 */
688 | 'a' 'a' /* rule 5 */
691 c: 'a' 'a' 'b' /* rule 6 */
697 [['b', 'a', 'a', 'a', 'b']],
710 'a' shift, and go to state 1
711 'b' shift, and go to state 2
712 'c' shift, and go to state 3
723 'a' shift, and go to state 5
734 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[18]])[
747 'a' shift, and go to state 8
757 $end shift, and go to state 11
765 'a' shift, and go to state 12
772 'a' shift, and go to state 13
779 'b' shift, and go to state 14
788 'a' shift, and go to state 15
793 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
795 ]AT_COND_CASE([[canonical LR]], [[$end]],
796 [[$default]])[ reduce using rule 7 (c)
801 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
803 ]AT_COND_CASE([[canonical LR]], [[$end]],
804 [[$default]])[ reduce using rule 3 (S)
817 5 | 'a' 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
819 ]AT_COND_CASE([[canonical LR]], [['a']],
820 [[$default]])[ reduce using rule 5 (A)
822 Conflict between rule 5 and token 'a' resolved as reduce (%left 'a').
827 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
829 ]AT_COND_CASE([[canonical LR]], [[$end]],
830 [[$default]])[ reduce using rule 1 (S)
835 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
837 ]AT_COND_CASE([[canonical LR]], [[$end]],
838 [[$default]])[ reduce using rule 2 (S)
847 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[19]],
849 'b' shift, and go to state 17
851 ]AT_COND_CASE([[canonical LR]], [[$end]],
852 [[$default]])[ reduce using rule 5 (A)
857 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
859 ]AT_COND_CASE([[canonical LR]], [['a']],
860 [[$default]])[ reduce using rule 4 (A)
865 6 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
867 ]AT_COND_CASE([[canonical LR]], [[$end]],
868 [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]],
877 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
881 State 19]AT_COND_CASE([[canonical LR]], [[
883 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
885 ]AT_COND_CASE([[canonical LR]], [[$end]],
886 [[$default]])[ reduce using rule 4 (A)
894 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]],
897 ]AT_COND_CASE([[canonical LR]], [['b']],
898 [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[
903 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['b']]])[
905 ]AT_COND_CASE([[canonical LR]], [['b']],
906 [[$default]])[ reduce using rule 4 (A)]])])[
912 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
913 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
915 [AT_COND_CASE([[LALR]],
919 AT_TEST_LR_TYPE([[Complex Lane Split]],
921 // Conflict resolution renders state 16 unreachable for canonical LR(1). We
922 // keep it so that the paser table diff is easier to code.
923 %define lr.keep-unreachable-state]],
925 /* Similar to the last test case set but forseeing the S/R conflict from the
926 first state that must be split is becoming difficult. Imagine if B were
927 even more complex. Imagine if A had other RHS's ending in other
944 [['b', 'a', 'a', 'a', 'b']],
957 'a' shift, and go to state 1
958 'b' shift, and go to state 2
959 'c' shift, and go to state 3
969 'a' shift, and go to state 5
979 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[19]])[
991 'a' shift, and go to state 8
1001 $end shift, and go to state 11
1008 'a' shift, and go to state 12
1015 'a' shift, and go to state 13
1022 'b' shift, and go to state 14
1030 'a' shift, and go to state 15
1035 8 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1037 ]AT_COND_CASE([[canonical LR]], [[$end]],
1038 [[$default]])[ reduce using rule 8 (c)
1043 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1045 ]AT_COND_CASE([[canonical LR]], [[$end]],
1046 [[$default]])[ reduce using rule 3 (S)
1060 6 | . %empty ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
1062 ]AT_COND_CASE([[canonical LR]], [['a']],
1063 [[$default]])[ reduce using rule 6 (B)
1067 Conflict between rule 6 and token 'a' resolved as reduce (%left 'a').
1072 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1074 ]AT_COND_CASE([[canonical LR]], [[$end]],
1075 [[$default]])[ reduce using rule 1 (S)
1080 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1082 ]AT_COND_CASE([[canonical LR]], [[$end]],
1083 [[$default]])[ reduce using rule 2 (S)
1093 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
1095 'b' shift, and go to state 18
1097 ]AT_COND_CASE([[canonical LR]], [[$end]],
1098 [[$default]])[ reduce using rule 6 (B)
1100 B go to state ]AT_COND_CASE([[canonical LR]], [[21]], [[17]])[
1105 5 B: 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
1107 ]AT_COND_CASE([[canonical LR]], [['a']],
1108 [[$default]])[ reduce using rule 5 (B)
1113 4 A: 'a' 'a' B .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
1115 ]AT_COND_CASE([[canonical LR]], [['a']],
1116 [[$default]])[ reduce using rule 4 (A)
1121 7 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1123 ]AT_COND_CASE([[canonical LR]], [[$end]],
1124 [[$default]])[ reduce using rule 7 (c)]AT_COND_CASE([[LALR]], [], [[
1131 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[22]],
1135 State 20]AT_COND_CASE([[canonical LR]], [[
1139 $end reduce using rule 5 (B)
1144 4 A: 'a' 'a' B . [$end]
1146 $end reduce using rule 4 (A)
1155 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[23]],
1158 ]AT_COND_CASE([[canonical LR]], [['b']],
1159 [[$default]])[ reduce using rule 6 (B)
1161 B go to state ]AT_COND_CASE([[canonical LR]], [[24
1168 'b' reduce using rule 5 (B)
1173 4 A: 'a' 'a' B . ['b']
1175 'b' reduce using rule 4 (A)]], [[17]])])[
1181 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
1182 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
1184 [AT_COND_CASE([[LALR]],
1188 AT_TEST_LR_TYPE([[Split During Added Lookahead Propagation]],
1189 [[%define lr.keep-unreachable-state]],
1191 /* The partial state chart diagram below is for LALR(1). State 0 is the start
1192 state. States are iterated for successor construction in numerical order.
1193 Transitions are downwards.
1195 State 13 has a R/R conflict that cannot be predicted by Bison's LR(1)
1196 algorithm using annotations alone. That is, when state 11's successor on
1197 'd' is merged with state 5 (which is originally just state 1's successor on
1198 'd'), state 5's successor on 'e' must then be changed because the resulting
1199 lookaheads that propagate to it now make it incompatible with state 8's
1200 successor on 'e'. In other words, state 13 must be split to avoid the
1218 This grammar is designed carefully to make sure that, despite Bison's LR(1)
1219 algorithm's bread-first iteration of transitions to reconstruct states,
1220 state 11's successors are constructed after state 5's and state 8's.
1221 Otherwise (for example, if you remove the first 'c' in each of rules 6 and
1222 7), state 5's successor on 'e' would never be merged with state 8's, so the
1223 split of the resulting state 13 would never need to be performed. */
1237 [['b', 'd', 'e', 'g']],
1240 [AT_COND_CASE([[LALR]],
1241 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1256 'a' shift, and go to state 1
1257 'b' shift, and go to state 2
1258 'c' shift, and go to state 3
1270 'd' shift, and go to state 5
1284 'd' shift, and go to state 8
1292 6 S: 'c' . 'c' A 'g'
1295 'c' shift, and go to state 11
1302 $end shift, and go to state 12
1310 'e' shift, and go to state ]AT_COND_CASE([[LALR]], [[13]],
1311 [[canonical LR]], [[13]],
1319 'f' shift, and go to state 14
1324 2 S: 'a' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1326 ]AT_COND_CASE([[canonical LR]], [[$end]],
1327 [[$default]])[ reduce using rule 2 (S)
1332 5 S: 'b' 'd' . [$end]
1336 'e' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
1339 ]AT_COND_CASE([[canonical LR]], [[$end]],
1340 [[$default]])[ reduce using rule 5 (S)
1347 'f' shift, and go to state 15
1354 'g' shift, and go to state 16
1359 6 S: 'c' 'c' . A 'g'
1364 'd' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]],
1375 $default accept]AT_COND_CASE([[LALR]], [[
1380 8 A: 'd' 'e' . ['f', 'g']
1381 9 B: 'd' 'e' . [$end, 'g']
1383 $end reduce using rule 9 (B)
1384 'g' reduce using rule 8 (A)
1385 'g' [reduce using rule 9 (B)]
1386 $default reduce using rule 8 (A)]], [[
1391 8 A: 'd' 'e' . ['f']
1392 9 B: 'd' 'e' . ]AT_COND_CASE([[canonical LR]], [[[$end]]], [[['g']]])[
1394 ]AT_COND_CASE([[canonical LR]], [[$end]],
1395 [['g' ]])[ reduce using rule 9 (B)
1396 ]AT_COND_CASE([[canonical LR]], [['f' ]],
1397 [[$default]])[ reduce using rule 8 (A)]])[
1402 1 S: 'a' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1404 ]AT_COND_CASE([[canonical LR]], [[$end]],
1405 [[$default]])[ reduce using rule 1 (S)
1410 3 S: 'b' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1412 ]AT_COND_CASE([[canonical LR]], [[$end]],
1413 [[$default]])[ reduce using rule 3 (S)
1418 4 S: 'b' B 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1420 ]AT_COND_CASE([[canonical LR]], [[$end]],
1421 [[$default]])[ reduce using rule 4 (S)
1426 6 S: 'c' 'c' A . 'g'
1428 'g' shift, and go to state 19
1433 7 S: 'c' 'c' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1435 ]AT_COND_CASE([[canonical LR]], [[$end]],
1436 [[$default]])[ reduce using rule 7 (S)
1441 6 S: 'c' 'c' A 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1443 ]AT_COND_CASE([[canonical LR]], [[$end]],
1444 [[$default]])[ reduce using rule 6 (S)]AT_COND_CASE([[LALR]],
1448 State 20]AT_COND_CASE([[canonical LR]], [[
1450 8 A: 'd' 'e' . ['f']
1451 9 B: 'd' 'e' . ['g']
1453 'f' reduce using rule 8 (A)
1454 'g' reduce using rule 9 (B)
1462 'e' shift, and go to state 22
1467 8 A: 'd' 'e' . ['g']
1468 9 B: 'd' 'e' . [$end]
1470 $end reduce using rule 9 (B)
1471 'g' reduce using rule 8 (A)]], [[
1473 8 A: 'd' 'e' . ['f', 'g']
1474 9 B: 'd' 'e' . [$end]
1476 $end reduce using rule 9 (B)
1477 $default reduce using rule 8 (A)]])])[
1483 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
1484 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
1486 [AT_COND_CASE([[LALR]],
1492 ## ------------------------------- ##
1493 ## %define lr.default-reduction. ##
1494 ## ------------------------------- ##
1496 # AT_TEST_LR_DEFAULT_REDUCTIONS(GRAMMAR, INPUT, TABLES)
1497 # -----------------------------------------------------
1498 m4_define([AT_TEST_LR_DEFAULT_REDUCTIONS],
1500 AT_TEST_TABLES_AND_PARSE([[no %define lr.default-reduction]],
1503 [$1], [$2], [[]], [$3])
1504 AT_TEST_TABLES_AND_PARSE([[%define lr.default-reduction most]],
1506 [[%define lr.default-reduction most]],
1507 [$1], [$2], [[]], [$3])
1508 AT_TEST_TABLES_AND_PARSE([[%define lr.default-reduction consistent]],
1509 [[consistent]], [[]],
1510 [[%define lr.default-reduction consistent]],
1511 [$1], [$2], [[]], [$3])
1512 AT_TEST_TABLES_AND_PARSE([[%define lr.default-reduction accepting]],
1513 [[accepting]], [[]],
1514 [[%define lr.default-reduction accepting]],
1515 [$1], [$2], [[]], [$3])
1518 AT_TEST_LR_DEFAULT_REDUCTIONS([[
1519 /* The start state is consistent and has a shift on 'a' and no reductions.
1520 After pushing the b below, enter an inconsistent state that has a shift and
1521 one reduction with one lookahead. */
1528 /* After shifting this 'a', enter a consistent state that has no shift and 1
1529 reduction with multiple lookaheads. */
1532 /* After the previous reduction, enter an inconsistent state that has no shift
1533 and multiple reductions. The first reduction has more lookaheads than the
1534 second, so the first should always be preferred as the default reduction if
1535 enabled. The second reduction has one lookahead. */
1539 dnl Visit each state mentioned above.
1543 0 $accept: . start $end
1549 'a' shift, and go to state 1
1557 4 a: 'a' .]AT_COND_CASE([[accepting]], [[ [$end, 'a', 'b']
1559 $end reduce using rule 4 (a)
1560 'a' reduce using rule 4 (a)
1561 'b' reduce using rule 4 (a)]], [[
1563 $default reduce using rule 4 (a)]])[
1568 0 $accept: start . $end
1570 $end shift, and go to state 4
1578 5 b: . %empty [$end, 'a']
1579 6 c: . %empty ['b']]AT_COND_CASE([[most]], [[
1581 'b' reduce using rule 6 (c)
1582 $default reduce using rule 5 (b)]], [[
1584 $end reduce using rule 5 (b)
1585 'a' reduce using rule 5 (b)
1586 'b' reduce using rule 6 (c)]])[
1594 0 $accept: start $end .
1601 1 start: a b . [$end]
1604 'a' shift, and go to state 7
1606 ]AT_COND_CASE([[most]], [[$default]],
1607 [[$end]])[ reduce using rule 1 (start)
1614 'b' shift, and go to state 8
1619 2 start: a b 'a' .]AT_COND_CASE([[accepting]], [[ [$end]
1621 $end reduce using rule 2 (start)]], [[
1623 $default reduce using rule 2 (start)]])[
1628 3 start: a c 'b' .]AT_COND_CASE([[accepting]], [[ [$end]
1630 $end reduce using rule 3 (start)]], [[
1632 $default reduce using rule 3 (start)]])[