1 # Exercising Bison Grammar Reduction. -*- Autotest -*-
2 # Copyright (C) 2001-2002, 2007-2010 Free Software Foundation, Inc.
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 AT_BANNER([[Grammar Reduction.]])
20 ## ------------------- ##
21 ## Useless Terminals. ##
22 ## ------------------- ##
24 AT_SETUP([Useless Terminals])
45 AT_BISON_CHECK([[input.y]])
47 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
48 [[Terminals unused in grammar
64 ## ---------------------- ##
65 ## Useless Nonterminals. ##
66 ## ---------------------- ##
68 AT_SETUP([Useless Nonterminals])
89 AT_BISON_CHECK([[input.y]], 0, [],
90 [[input.y: warning: 9 nonterminals useless in grammar
91 input.y:4.8-15: warning: nonterminal useless in grammar: useless1
92 input.y:5.8-15: warning: nonterminal useless in grammar: useless2
93 input.y:6.8-15: warning: nonterminal useless in grammar: useless3
94 input.y:7.8-15: warning: nonterminal useless in grammar: useless4
95 input.y:8.8-15: warning: nonterminal useless in grammar: useless5
96 input.y:9.8-15: warning: nonterminal useless in grammar: useless6
97 input.y:10.8-15: warning: nonterminal useless in grammar: useless7
98 input.y:11.8-15: warning: nonterminal useless in grammar: useless8
99 input.y:12.8-15: warning: nonterminal useless in grammar: useless9
102 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
103 [[Nonterminals useless in grammar
119 ## --------------- ##
121 ## --------------- ##
123 AT_SETUP([Useless Rules])
125 AT_KEYWORDS([report])
144 AT_BISON_CHECK([[input.y]], 0, [],
145 [[input.y: warning: 9 nonterminals useless in grammar
146 input.y: warning: 9 rules useless in grammar
147 input.y:6.1-8: warning: nonterminal useless in grammar: useless1
148 input.y:7.1-8: warning: nonterminal useless in grammar: useless2
149 input.y:8.1-8: warning: nonterminal useless in grammar: useless3
150 input.y:9.1-8: warning: nonterminal useless in grammar: useless4
151 input.y:10.1-8: warning: nonterminal useless in grammar: useless5
152 input.y:11.1-8: warning: nonterminal useless in grammar: useless6
153 input.y:12.1-8: warning: nonterminal useless in grammar: useless7
154 input.y:13.1-8: warning: nonterminal useless in grammar: useless8
155 input.y:14.1-8: warning: nonterminal useless in grammar: useless9
156 input.y:6.11-13: warning: rule useless in grammar: useless1: '1'
157 input.y:7.11-13: warning: rule useless in grammar: useless2: '2'
158 input.y:8.11-13: warning: rule useless in grammar: useless3: '3'
159 input.y:9.11-13: warning: rule useless in grammar: useless4: '4'
160 input.y:10.11-13: warning: rule useless in grammar: useless5: '5'
161 input.y:11.11-13: warning: rule useless in grammar: useless6: '6'
162 input.y:12.11-13: warning: rule useless in grammar: useless7: '7'
163 input.y:13.11-13: warning: rule useless in grammar: useless8: '8'
164 input.y:14.11-13: warning: rule useless in grammar: useless9: '9'
167 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
168 [[Nonterminals useless in grammar
178 Terminals unused in grammar
188 Rules useless in grammar
204 ## ------------------- ##
205 ## Reduced Automaton. ##
206 ## ------------------- ##
208 # Check that the automaton is that as the for the grammar reduced by
211 AT_SETUP([Reduced Automaton])
213 AT_KEYWORDS([report])
215 # The non reduced grammar.
216 # ------------------------
217 AT_DATA([[not-reduced.y]],
218 [[/* A useless token. */
223 %output "not-reduced.c"
227 exp: useful { /* A useful action. */ }
228 | non_productive { /* A non productive action. */ }
231 not_reachable: useful { /* A not reachable action. */ }
234 non_productive: non_productive useless_token
235 { /* Another non productive action. */ }
240 AT_BISON_CHECK([[not-reduced.y]], 0, [],
241 [[not-reduced.y: warning: 2 nonterminals useless in grammar
242 not-reduced.y: warning: 3 rules useless in grammar
243 not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable
244 not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive
245 not-reduced.y:11.6-57: warning: rule useless in grammar: exp: non_productive
246 not-reduced.y:14.16-56: warning: rule useless in grammar: not_reachable: useful
247 not-reduced.y:17.17-18.63: warning: rule useless in grammar: non_productive: non_productive useless_token
250 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
251 [[Nonterminals useless in grammar
254 Terminals unused in grammar
256 Rules useless in grammar
257 2 exp: non_productive
258 3 not_reachable: useful
259 4 non_productive: non_productive useless_token
262 # The reduced grammar.
263 # --------------------
264 AT_DATA([[reduced.y]],
265 [[/* A useless token. */
274 exp: useful { /* A useful action. */ }
275 // | non_productive { /* A non productive action. */ } */
278 //not_reachable: useful { /* A not reachable action. */ }
281 //non_productive: non_productive useless_token
282 // { /* Another non productive action. */ }
287 AT_BISON_CHECK([[reduced.y]])
289 # Comparing the parsers.
291 AT_CHECK([sed 's/not-reduced/reduced/g' not-reduced.c], 0, [expout])
297 ## ------------------- ##
298 ## Underivable Rules. ##
299 ## ------------------- ##
301 AT_SETUP([Underivable Rules])
303 AT_KEYWORDS([report])
310 exp: useful | underivable;
311 underivable: indirection;
312 indirection: underivable;
315 AT_BISON_CHECK([[input.y]], 0, [],
316 [[input.y: warning: 2 nonterminals useless in grammar
317 input.y: warning: 3 rules useless in grammar
318 input.y:5.15-25: warning: nonterminal useless in grammar: underivable
319 input.y:6.14-24: warning: nonterminal useless in grammar: indirection
320 input.y:5.15-25: warning: rule useless in grammar: exp: underivable
321 input.y:6.14-24: warning: rule useless in grammar: underivable: indirection
322 input.y:7.14-24: warning: rule useless in grammar: indirection: underivable
325 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
326 [[Nonterminals useless in grammar
329 Rules useless in grammar
331 3 underivable: indirection
332 4 indirection: underivable
339 ## ---------------- ##
340 ## Empty Language. ##
341 ## ---------------- ##
343 AT_SETUP([Empty Language])
351 AT_BISON_CHECK([[input.y]], 1, [],
352 [[input.y: warning: 2 nonterminals useless in grammar
353 input.y: warning: 2 rules useless in grammar
354 input.y:3.1-3: fatal error: start symbol exp does not derive any sentence
361 ## ----------------- ##
362 ## %define lr.type. ##
363 ## ----------------- ##
365 # AT_TEST_LR_TYPE(DESCRIPTION,
366 # DECLS, GRAMMAR, INPUT,
367 # BISON-STDERR, TABLES,
369 # [PARSER-EXIT-VALUE],
370 # [PARSER-STDOUT], [PARSER-STDERR])
371 # -------------------------------------------------
372 m4_define([AT_TEST_LR_TYPE],
374 AT_TEST_TABLES_AND_PARSE([[no %define lr.type: ]$1],
376 [$2], m4_shiftn(2, $@))
377 AT_TEST_TABLES_AND_PARSE([[%define lr.type lalr: ]$1],
379 [[%define lr.type lalr
382 AT_TEST_TABLES_AND_PARSE([[%define lr.type ielr: ]$1],
384 [[%define lr.type ielr
387 AT_TEST_TABLES_AND_PARSE([[%define lr.type canonical-lr: ]$1],
388 [[canonical LR]], [[]],
389 [[%define lr.type canonical-lr
394 AT_TEST_LR_TYPE([[Single State Split]],
396 // Conflict resolution renders state 12 unreachable for canonical LR(1). We
397 // keep it so that the paser table diff is easier to code.
398 %define lr.keep-unreachable-states]],
400 S: 'a' A 'a' /* rule 1 */
401 | 'b' A 'b' /* rule 2 */
405 /* A conflict should appear after the first 'a' in rules 4 and 5 but only after
406 having shifted the first 'a' in rule 1. However, when LALR(1) merging is
407 chosen, the state containing that conflict is reused after having seen the
408 first 'b' in rule 2 and then the first 'a' in rules 4 and 5. In both cases,
409 because of the merged state, if the next token is an 'a', the %left forces a
410 reduction action with rule 5. In the latter case, only a shift is actually
411 grammatically correct. Thus, the parser would report a syntax error for the
412 grammatically correct sentence "baab" because it would encounter a syntax
413 error after that incorrect reduction.
415 Despite not being LALR(1), Menhir version 20070322 suffers from this problem
416 as well. It uses David Pager's weak compatibility test for merging states.
417 Bison and Menhir accept non-LR(1) grammars with conflict resolution. Pager
418 designed his algorithm only for LR(1) grammars. */
419 A: 'a' 'a' /* rule 4 */
423 /* Rule 3, rule 6, and rule 7 ensure that Bison does not report rule 4 as
424 useless after conflict resolution. This proves that, even though LALR(1)
425 generates incorrect parser tables sometimes, Bison will not necessarily
426 produce any warning to help the user realize it. */
427 c: 'a' 'b' /* rule 6 */
433 [['b', 'a', 'a', 'b']],
446 'a' shift, and go to state 1
447 'b' shift, and go to state 2
448 'c' shift, and go to state 3
459 'a' shift, and go to state 5
470 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[16]])[
483 'a' shift, and go to state 8
493 $end shift, and go to state 11
499 5 | 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
501 ]AT_COND_CASE([[canonical LR]], [['a']],
502 [[$default]])[ reduce using rule 5 (A)
504 Conflict between rule 5 and token 'a' resolved as reduce (%left 'a').
511 'a' shift, and go to state 13
518 'b' shift, and go to state 14
527 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[17]],
529 'b' shift, and go to state 15
531 ]AT_COND_CASE([[canonical LR]], [[$end]],
532 [[$default]])[ reduce using rule 5 (A)
537 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
539 ]AT_COND_CASE([[canonical LR]], [[$end]],
540 [[$default]])[ reduce using rule 7 (c)
545 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
547 ]AT_COND_CASE([[canonical LR]], [[$end]],
548 [[$default]])[ reduce using rule 3 (S)
560 4 A: 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
562 ]AT_COND_CASE([[canonical LR]], [['a']],
563 [[$default]])[ reduce using rule 4 (A)
568 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
570 ]AT_COND_CASE([[canonical LR]], [[$end]],
571 [[$default]])[ reduce using rule 1 (S)
576 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
578 ]AT_COND_CASE([[canonical LR]], [[$end]],
579 [[$default]])[ reduce using rule 2 (S)
584 6 c: 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
586 ]AT_COND_CASE([[canonical LR]], [[$end]],
587 [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]],
596 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[18]],
599 ]AT_COND_CASE([[canonical LR]], [['b']],
600 [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[
605 4 A: 'a' 'a' . [$end]
607 $end reduce using rule 4 (A)
614 'b' reduce using rule 4 (A)]])])[
620 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
621 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
623 [AT_COND_CASE([[LALR]],
627 AT_TEST_LR_TYPE([[Lane Split]],
629 // Conflict resolution renders state 16 unreachable for canonical LR(1). We
630 // keep it so that the paser table diff is easier to code.
631 %define lr.keep-unreachable-states]],
633 /* Similar to the last test case set but two states must be split. */
634 S: 'a' A 'a' /* rule 1 */
635 | 'b' A 'b' /* rule 2 */
639 A: 'a' 'a' 'a' /* rule 4 */
640 | 'a' 'a' /* rule 5 */
643 c: 'a' 'a' 'b' /* rule 6 */
649 [['b', 'a', 'a', 'a', 'b']],
662 'a' shift, and go to state 1
663 'b' shift, and go to state 2
664 'c' shift, and go to state 3
675 'a' shift, and go to state 5
686 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[18]])[
699 'a' shift, and go to state 8
709 $end shift, and go to state 11
717 'a' shift, and go to state 12
724 'a' shift, and go to state 13
731 'b' shift, and go to state 14
740 'a' shift, and go to state 15
745 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
747 ]AT_COND_CASE([[canonical LR]], [[$end]],
748 [[$default]])[ reduce using rule 7 (c)
753 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
755 ]AT_COND_CASE([[canonical LR]], [[$end]],
756 [[$default]])[ reduce using rule 3 (S)
769 5 | 'a' 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
771 ]AT_COND_CASE([[canonical LR]], [['a']],
772 [[$default]])[ reduce using rule 5 (A)
774 Conflict between rule 5 and token 'a' resolved as reduce (%left 'a').
779 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
781 ]AT_COND_CASE([[canonical LR]], [[$end]],
782 [[$default]])[ reduce using rule 1 (S)
787 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
789 ]AT_COND_CASE([[canonical LR]], [[$end]],
790 [[$default]])[ reduce using rule 2 (S)
799 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[19]],
801 'b' shift, and go to state 17
803 ]AT_COND_CASE([[canonical LR]], [[$end]],
804 [[$default]])[ reduce using rule 5 (A)
809 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
811 ]AT_COND_CASE([[canonical LR]], [['a']],
812 [[$default]])[ reduce using rule 4 (A)
817 6 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
819 ]AT_COND_CASE([[canonical LR]], [[$end]],
820 [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]],
829 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
833 state 19]AT_COND_CASE([[canonical LR]], [[
835 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
837 ]AT_COND_CASE([[canonical LR]], [[$end]],
838 [[$default]])[ reduce using rule 4 (A)
846 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]],
849 ]AT_COND_CASE([[canonical LR]], [['b']],
850 [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[
855 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['b']]])[
857 ]AT_COND_CASE([[canonical LR]], [['b']],
858 [[$default]])[ reduce using rule 4 (A)]])])[
864 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
865 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
867 [AT_COND_CASE([[LALR]],
871 AT_TEST_LR_TYPE([[Complex Lane Split]],
873 // Conflict resolution renders state 16 unreachable for canonical LR(1). We
874 // keep it so that the paser table diff is easier to code.
875 %define lr.keep-unreachable-states]],
877 /* Similar to the last test case set but forseeing the S/R conflict from the
878 first state that must be split is becoming difficult. Imagine if B were
879 even more complex. Imagine if A had other RHS's ending in other
896 [['b', 'a', 'a', 'a', 'b']],
909 'a' shift, and go to state 1
910 'b' shift, and go to state 2
911 'c' shift, and go to state 3
921 'a' shift, and go to state 5
931 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[19]])[
943 'a' shift, and go to state 8
953 $end shift, and go to state 11
960 'a' shift, and go to state 12
967 'a' shift, and go to state 13
974 'b' shift, and go to state 14
982 'a' shift, and go to state 15
987 8 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
989 ]AT_COND_CASE([[canonical LR]], [[$end]],
990 [[$default]])[ reduce using rule 8 (c)
995 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
997 ]AT_COND_CASE([[canonical LR]], [[$end]],
998 [[$default]])[ reduce using rule 3 (S)
1012 6 | . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
1014 ]AT_COND_CASE([[canonical LR]], [['a']],
1015 [[$default]])[ reduce using rule 6 (B)
1019 Conflict between rule 6 and token 'a' resolved as reduce (%left 'a').
1024 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1026 ]AT_COND_CASE([[canonical LR]], [[$end]],
1027 [[$default]])[ reduce using rule 1 (S)
1032 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1034 ]AT_COND_CASE([[canonical LR]], [[$end]],
1035 [[$default]])[ reduce using rule 2 (S)
1045 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
1047 'b' shift, and go to state 18
1049 ]AT_COND_CASE([[canonical LR]], [[$end]],
1050 [[$default]])[ reduce using rule 6 (B)
1052 B go to state ]AT_COND_CASE([[canonical LR]], [[21]], [[17]])[
1057 5 B: 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
1059 ]AT_COND_CASE([[canonical LR]], [['a']],
1060 [[$default]])[ reduce using rule 5 (B)
1065 4 A: 'a' 'a' B .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
1067 ]AT_COND_CASE([[canonical LR]], [['a']],
1068 [[$default]])[ reduce using rule 4 (A)
1073 7 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1075 ]AT_COND_CASE([[canonical LR]], [[$end]],
1076 [[$default]])[ reduce using rule 7 (c)]AT_COND_CASE([[LALR]], [], [[
1083 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[22]],
1087 state 20]AT_COND_CASE([[canonical LR]], [[
1091 $end reduce using rule 5 (B)
1096 4 A: 'a' 'a' B . [$end]
1098 $end reduce using rule 4 (A)
1107 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[23]],
1110 ]AT_COND_CASE([[canonical LR]], [['b']],
1111 [[$default]])[ reduce using rule 6 (B)
1113 B go to state ]AT_COND_CASE([[canonical LR]], [[24
1120 'b' reduce using rule 5 (B)
1125 4 A: 'a' 'a' B . ['b']
1127 'b' reduce using rule 4 (A)]], [[17]])])[
1133 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
1134 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
1136 [AT_COND_CASE([[LALR]],
1140 AT_TEST_LR_TYPE([[Split During Added Lookahead Propagation]],
1141 [[%define lr.keep-unreachable-states]],
1143 /* The partial state chart diagram below is for LALR(1). State 0 is the start
1144 state. States are iterated for successor construction in numerical order.
1145 Transitions are downwards.
1147 State 13 has a R/R conflict that cannot be predicted by Bison's LR(1)
1148 algorithm using annotations alone. That is, when state 11's successor on
1149 'd' is merged with state 5 (which is originally just state 1's successor on
1150 'd'), state 5's successor on 'e' must then be changed because the resulting
1151 lookaheads that propagate to it now make it incompatible with state 8's
1152 successor on 'e'. In other words, state 13 must be split to avoid the
1170 This grammar is designed carefully to make sure that, despite Bison's LR(1)
1171 algorithm's bread-first iteration of transitions to reconstruct states,
1172 state 11's successors are constructed after state 5's and state 8's.
1173 Otherwise (for example, if you remove the first 'c' in each of rules 6 and
1174 7), state 5's successor on 'e' would never be merged with state 8's, so the
1175 split of the resulting state 13 would never need to be performed. */
1189 [['b', 'd', 'e', 'g']],
1192 [AT_COND_CASE([[LALR]],
1193 [[input.y: conflicts: 1 reduce/reduce
1208 'a' shift, and go to state 1
1209 'b' shift, and go to state 2
1210 'c' shift, and go to state 3
1222 'd' shift, and go to state 5
1236 'd' shift, and go to state 8
1244 6 S: 'c' . 'c' A 'g'
1247 'c' shift, and go to state 11
1254 $end shift, and go to state 12
1262 'e' shift, and go to state ]AT_COND_CASE([[LALR]], [[13]],
1263 [[canonical LR]], [[13]],
1271 'f' shift, and go to state 14
1276 2 S: 'a' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1278 ]AT_COND_CASE([[canonical LR]], [[$end]],
1279 [[$default]])[ reduce using rule 2 (S)
1284 5 S: 'b' 'd' . [$end]
1288 'e' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
1291 ]AT_COND_CASE([[canonical LR]], [[$end]],
1292 [[$default]])[ reduce using rule 5 (S)
1299 'f' shift, and go to state 15
1306 'g' shift, and go to state 16
1311 6 S: 'c' 'c' . A 'g'
1316 'd' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]],
1327 $default accept]AT_COND_CASE([[LALR]], [[
1332 8 A: 'd' 'e' . ['f', 'g']
1333 9 B: 'd' 'e' . [$end, 'g']
1335 $end reduce using rule 9 (B)
1336 'g' reduce using rule 8 (A)
1337 'g' [reduce using rule 9 (B)]
1338 $default reduce using rule 8 (A)]], [[
1343 8 A: 'd' 'e' . ['f']
1344 9 B: 'd' 'e' . ]AT_COND_CASE([[canonical LR]], [[[$end]]], [[['g']]])[
1346 ]AT_COND_CASE([[canonical LR]], [[$end]],
1347 [['g' ]])[ reduce using rule 9 (B)
1348 ]AT_COND_CASE([[canonical LR]], [['f' ]],
1349 [[$default]])[ reduce using rule 8 (A)]])[
1354 1 S: 'a' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1356 ]AT_COND_CASE([[canonical LR]], [[$end]],
1357 [[$default]])[ reduce using rule 1 (S)
1362 3 S: 'b' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1364 ]AT_COND_CASE([[canonical LR]], [[$end]],
1365 [[$default]])[ reduce using rule 3 (S)
1370 4 S: 'b' B 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1372 ]AT_COND_CASE([[canonical LR]], [[$end]],
1373 [[$default]])[ reduce using rule 4 (S)
1378 6 S: 'c' 'c' A . 'g'
1380 'g' shift, and go to state 19
1385 7 S: 'c' 'c' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1387 ]AT_COND_CASE([[canonical LR]], [[$end]],
1388 [[$default]])[ reduce using rule 7 (S)
1393 6 S: 'c' 'c' A 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1395 ]AT_COND_CASE([[canonical LR]], [[$end]],
1396 [[$default]])[ reduce using rule 6 (S)]AT_COND_CASE([[LALR]],
1400 state 20]AT_COND_CASE([[canonical LR]], [[
1402 8 A: 'd' 'e' . ['f']
1403 9 B: 'd' 'e' . ['g']
1405 'f' reduce using rule 8 (A)
1406 'g' reduce using rule 9 (B)
1414 'e' shift, and go to state 22
1419 8 A: 'd' 'e' . ['g']
1420 9 B: 'd' 'e' . [$end]
1422 $end reduce using rule 9 (B)
1423 'g' reduce using rule 8 (A)]], [[
1425 8 A: 'd' 'e' . ['f', 'g']
1426 9 B: 'd' 'e' . [$end]
1428 $end reduce using rule 9 (B)
1429 $default reduce using rule 8 (A)]])])[
1435 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
1436 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
1438 [AT_COND_CASE([[LALR]],
1444 ## ------------------------------- ##
1445 ## %define lr.default-reductions. ##
1446 ## ------------------------------- ##
1448 # AT_TEST_LR_DEFAULT_REDUCTIONS(GRAMMAR, INPUT, TABLES)
1449 # -----------------------------------------------------
1450 m4_define([AT_TEST_LR_DEFAULT_REDUCTIONS],
1452 AT_TEST_TABLES_AND_PARSE([[no %define lr.default-reductions]],
1455 [$1], [$2], [[]], [$3])
1456 AT_TEST_TABLES_AND_PARSE([[%define lr.default-reductions all]],
1458 [[%define lr.default-reductions all]],
1459 [$1], [$2], [[]], [$3])
1460 AT_TEST_TABLES_AND_PARSE([[%define lr.default-reductions consistent]],
1461 [[consistent]], [[]],
1462 [[%define lr.default-reductions consistent]],
1463 [$1], [$2], [[]], [$3])
1464 AT_TEST_TABLES_AND_PARSE([[%define lr.default-reductions accepting]],
1465 [[accepting]], [[]],
1466 [[%define lr.default-reductions accepting]],
1467 [$1], [$2], [[]], [$3])
1470 AT_TEST_LR_DEFAULT_REDUCTIONS([[
1471 /* The start state is consistent and has a shift on 'a' and no reductions.
1472 After pushing the b below, enter an inconsistent state that has a shift and
1473 one reduction with one lookahead. */
1480 /* After shifting this 'a', enter a consistent state that has no shift and 1
1481 reduction with multiple lookaheads. */
1484 /* After the previous reduction, enter an inconsistent state that has no shift
1485 and multiple reductions. The first reduction has more lookaheads than the
1486 second, so the first should always be preferred as the default reduction if
1487 enabled. The second reduction has one lookahead. */
1491 dnl Visit each state mentioned above.
1495 0 $accept: . start $end
1501 'a' shift, and go to state 1
1509 4 a: 'a' .]AT_COND_CASE([[accepting]], [[ [$end, 'a', 'b']
1511 $end reduce using rule 4 (a)
1512 'a' reduce using rule 4 (a)
1513 'b' reduce using rule 4 (a)]], [[
1515 $default reduce using rule 4 (a)]])[
1520 0 $accept: start . $end
1522 $end shift, and go to state 4
1531 6 c: . ['b']]AT_COND_CASE([[all]], [[
1533 'b' reduce using rule 6 (c)
1534 $default reduce using rule 5 (b)]], [[
1536 $end reduce using rule 5 (b)
1537 'a' reduce using rule 5 (b)
1538 'b' reduce using rule 6 (c)]])[
1546 0 $accept: start $end .
1553 1 start: a b . [$end]
1556 'a' shift, and go to state 7
1558 ]AT_COND_CASE([[all]], [[$default]], [[$end]])[ reduce using rule 1 (start)
1565 'b' shift, and go to state 8
1570 2 start: a b 'a' .]AT_COND_CASE([[accepting]], [[ [$end]
1572 $end reduce using rule 2 (start)]], [[
1574 $default reduce using rule 2 (start)]])[
1579 3 start: a c 'b' .]AT_COND_CASE([[accepting]], [[ [$end]
1581 $end reduce using rule 3 (start)]], [[
1583 $default reduce using rule 3 (start)]])[