1 # Exercising Bison Grammar Reduction. -*- Autotest -*-
3 # Copyright (C) 2001, 2002, 2007, 2008, 2009, 2010 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 <http://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])
91 AT_BISON_CHECK([[input.y]], 0, [],
92 [[input.y: warning: 9 nonterminals useless in grammar
93 input.y:4.8-15: warning: nonterminal useless in grammar: useless1
94 input.y:5.8-15: warning: nonterminal useless in grammar: useless2
95 input.y:6.8-15: warning: nonterminal useless in grammar: useless3
96 input.y:7.8-15: warning: nonterminal useless in grammar: useless4
97 input.y:8.8-15: warning: nonterminal useless in grammar: useless5
98 input.y:9.8-15: warning: nonterminal useless in grammar: useless6
99 input.y:10.8-15: warning: nonterminal useless in grammar: useless7
100 input.y:11.8-15: warning: nonterminal useless in grammar: useless8
101 input.y:12.8-15: warning: nonterminal useless in grammar: useless9
104 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
105 [[Nonterminals useless in grammar
121 ## --------------- ##
123 ## --------------- ##
125 AT_SETUP([Useless Rules])
127 AT_KEYWORDS([report])
146 AT_BISON_CHECK([[input.y]], 0, [],
147 [[input.y: warning: 9 nonterminals useless in grammar
148 input.y: warning: 9 rules useless in grammar
149 input.y:6.1-8: warning: nonterminal useless in grammar: useless1
150 input.y:7.1-8: warning: nonterminal useless in grammar: useless2
151 input.y:8.1-8: warning: nonterminal useless in grammar: useless3
152 input.y:9.1-8: warning: nonterminal useless in grammar: useless4
153 input.y:10.1-8: warning: nonterminal useless in grammar: useless5
154 input.y:11.1-8: warning: nonterminal useless in grammar: useless6
155 input.y:12.1-8: warning: nonterminal useless in grammar: useless7
156 input.y:13.1-8: warning: nonterminal useless in grammar: useless8
157 input.y:14.1-8: warning: nonterminal useless in grammar: useless9
158 input.y:6.11-13: warning: rule useless in grammar: useless1: '1'
159 input.y:7.11-13: warning: rule useless in grammar: useless2: '2'
160 input.y:8.11-13: warning: rule useless in grammar: useless3: '3'
161 input.y:9.11-13: warning: rule useless in grammar: useless4: '4'
162 input.y:10.11-13: warning: rule useless in grammar: useless5: '5'
163 input.y:11.11-13: warning: rule useless in grammar: useless6: '6'
164 input.y:12.11-13: warning: rule useless in grammar: useless7: '7'
165 input.y:13.11-13: warning: rule useless in grammar: useless8: '8'
166 input.y:14.11-13: warning: rule useless in grammar: useless9: '9'
169 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
170 [[Nonterminals useless in grammar
180 Terminals unused in grammar
190 Rules useless in grammar
206 ## ------------------- ##
207 ## Reduced Automaton. ##
208 ## ------------------- ##
210 # Check that the automaton is that as the for the grammar reduced by
213 AT_SETUP([Reduced Automaton])
215 AT_KEYWORDS([report])
217 # The non reduced grammar.
218 # ------------------------
219 AT_DATA([[not-reduced.y]],
220 [[/* A useless token. */
225 %output "not-reduced.c"
229 exp: useful { /* A useful action. */ }
230 | non_productive { /* A non productive action. */ }
233 not_reachable: useful { /* A not reachable action. */ }
236 non_productive: non_productive useless_token
237 { /* Another non productive action. */ }
242 AT_BISON_CHECK([[not-reduced.y]], 0, [],
243 [[not-reduced.y: warning: 2 nonterminals useless in grammar
244 not-reduced.y: warning: 3 rules useless in grammar
245 not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable
246 not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive
247 not-reduced.y:11.6-57: warning: rule useless in grammar: exp: non_productive
248 not-reduced.y:14.16-56: warning: rule useless in grammar: not_reachable: useful
249 not-reduced.y:17.17-18.63: warning: rule useless in grammar: non_productive: non_productive useless_token
252 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
253 [[Nonterminals useless in grammar
256 Terminals unused in grammar
258 Rules useless in grammar
259 2 exp: non_productive
260 3 not_reachable: useful
261 4 non_productive: non_productive useless_token
264 # The reduced grammar.
265 # --------------------
266 AT_DATA([[reduced.y]],
267 [[/* A useless token. */
276 exp: useful { /* A useful action. */ }
277 // | non_productive { /* A non productive action. */ } */
280 //not_reachable: useful { /* A not reachable action. */ }
283 //non_productive: non_productive useless_token
284 // { /* Another non productive action. */ }
289 AT_BISON_CHECK([[reduced.y]])
291 # Comparing the parsers.
293 AT_CHECK([sed 's/not-reduced/reduced/g' not-reduced.c], 0, [expout])
299 ## ------------------- ##
300 ## Underivable Rules. ##
301 ## ------------------- ##
303 AT_SETUP([Underivable Rules])
305 AT_KEYWORDS([report])
312 exp: useful | underivable;
313 underivable: indirection;
314 indirection: underivable;
317 AT_BISON_CHECK([[input.y]], 0, [],
318 [[input.y: warning: 2 nonterminals useless in grammar
319 input.y: warning: 3 rules useless in grammar
320 input.y:5.15-25: warning: nonterminal useless in grammar: underivable
321 input.y:6.14-24: warning: nonterminal useless in grammar: indirection
322 input.y:5.15-25: warning: rule useless in grammar: exp: underivable
323 input.y:6.14-24: warning: rule useless in grammar: underivable: indirection
324 input.y:7.14-24: warning: rule useless in grammar: indirection: underivable
327 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
328 [[Nonterminals useless in grammar
331 Rules useless in grammar
333 3 underivable: indirection
334 4 indirection: underivable
341 ## ---------------- ##
342 ## Empty Language. ##
343 ## ---------------- ##
345 AT_SETUP([Empty Language])
353 AT_BISON_CHECK([[input.y]], 1, [],
354 [[input.y: warning: 2 nonterminals useless in grammar
355 input.y: warning: 2 rules useless in grammar
356 input.y:3.1-3: fatal error: start symbol exp does not derive any sentence
363 ## ----------------- ##
364 ## %define lr.type. ##
365 ## ----------------- ##
367 # AT_TEST_LR_TYPE(DESCRIPTION,
368 # DECLS, GRAMMAR, INPUT,
369 # BISON-STDERR, TABLES,
371 # [PARSER-EXIT-VALUE],
372 # [PARSER-STDOUT], [PARSER-STDERR])
373 # -------------------------------------------------
374 m4_define([AT_TEST_LR_TYPE],
376 AT_TEST_TABLES_AND_PARSE([[no %define lr.type: ]$1],
378 [$2], m4_shiftn(2, $@))
379 AT_TEST_TABLES_AND_PARSE([[%define lr.type lalr: ]$1],
381 [[%define lr.type lalr
384 AT_TEST_TABLES_AND_PARSE([[%define lr.type ielr: ]$1],
386 [[%define lr.type ielr
389 AT_TEST_TABLES_AND_PARSE([[%define lr.type canonical-lr: ]$1],
390 [[canonical LR]], [[]],
391 [[%define lr.type canonical-lr
396 AT_TEST_LR_TYPE([[Single State Split]],
398 // Conflict resolution renders state 12 unreachable for canonical LR(1). We
399 // keep it so that the paser table diff is easier to code.
400 %define lr.keep-unreachable-states]],
402 S: 'a' A 'a' /* rule 1 */
403 | 'b' A 'b' /* rule 2 */
407 /* A conflict should appear after the first 'a' in rules 4 and 5 but only after
408 having shifted the first 'a' in rule 1. However, when LALR(1) merging is
409 chosen, the state containing that conflict is reused after having seen the
410 first 'b' in rule 2 and then the first 'a' in rules 4 and 5. In both cases,
411 because of the merged state, if the next token is an 'a', the %left forces a
412 reduction action with rule 5. In the latter case, only a shift is actually
413 grammatically correct. Thus, the parser would report a syntax error for the
414 grammatically correct sentence "baab" because it would encounter a syntax
415 error after that incorrect reduction.
417 Despite not being LALR(1), Menhir version 20070322 suffers from this problem
418 as well. It uses David Pager's weak compatibility test for merging states.
419 Bison and Menhir accept non-LR(1) grammars with conflict resolution. Pager
420 designed his algorithm only for LR(1) grammars. */
421 A: 'a' 'a' /* rule 4 */
425 /* Rule 3, rule 6, and rule 7 ensure that Bison does not report rule 4 as
426 useless after conflict resolution. This proves that, even though LALR(1)
427 generates incorrect parser tables sometimes, Bison will not necessarily
428 produce any warning to help the user realize it. */
429 c: 'a' 'b' /* rule 6 */
435 [['b', 'a', 'a', 'b']],
448 'a' shift, and go to state 1
449 'b' shift, and go to state 2
450 'c' shift, and go to state 3
461 'a' shift, and go to state 5
472 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[16]])[
485 'a' shift, and go to state 8
495 $end shift, and go to state 11
501 5 | 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
503 ]AT_COND_CASE([[canonical LR]], [['a']],
504 [[$default]])[ reduce using rule 5 (A)
506 Conflict between rule 5 and token 'a' resolved as reduce (%left 'a').
513 'a' shift, and go to state 13
520 'b' shift, and go to state 14
529 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[17]],
531 'b' shift, and go to state 15
533 ]AT_COND_CASE([[canonical LR]], [[$end]],
534 [[$default]])[ reduce using rule 5 (A)
539 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
541 ]AT_COND_CASE([[canonical LR]], [[$end]],
542 [[$default]])[ reduce using rule 7 (c)
547 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
549 ]AT_COND_CASE([[canonical LR]], [[$end]],
550 [[$default]])[ reduce using rule 3 (S)
562 4 A: 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
564 ]AT_COND_CASE([[canonical LR]], [['a']],
565 [[$default]])[ reduce using rule 4 (A)
570 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
572 ]AT_COND_CASE([[canonical LR]], [[$end]],
573 [[$default]])[ reduce using rule 1 (S)
578 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
580 ]AT_COND_CASE([[canonical LR]], [[$end]],
581 [[$default]])[ reduce using rule 2 (S)
586 6 c: 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
588 ]AT_COND_CASE([[canonical LR]], [[$end]],
589 [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]],
598 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[18]],
601 ]AT_COND_CASE([[canonical LR]], [['b']],
602 [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[
607 4 A: 'a' 'a' . [$end]
609 $end reduce using rule 4 (A)
616 'b' reduce using rule 4 (A)]])])[
622 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
623 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
625 [AT_COND_CASE([[LALR]],
629 AT_TEST_LR_TYPE([[Lane Split]],
631 // Conflict resolution renders state 16 unreachable for canonical LR(1). We
632 // keep it so that the paser table diff is easier to code.
633 %define lr.keep-unreachable-states]],
635 /* Similar to the last test case set but two states must be split. */
636 S: 'a' A 'a' /* rule 1 */
637 | 'b' A 'b' /* rule 2 */
641 A: 'a' 'a' 'a' /* rule 4 */
642 | 'a' 'a' /* rule 5 */
645 c: 'a' 'a' 'b' /* rule 6 */
651 [['b', 'a', 'a', 'a', 'b']],
664 'a' shift, and go to state 1
665 'b' shift, and go to state 2
666 'c' shift, and go to state 3
677 'a' shift, and go to state 5
688 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[18]])[
701 'a' shift, and go to state 8
711 $end shift, and go to state 11
719 'a' shift, and go to state 12
726 'a' shift, and go to state 13
733 'b' shift, and go to state 14
742 'a' shift, and go to state 15
747 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
749 ]AT_COND_CASE([[canonical LR]], [[$end]],
750 [[$default]])[ reduce using rule 7 (c)
755 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
757 ]AT_COND_CASE([[canonical LR]], [[$end]],
758 [[$default]])[ reduce using rule 3 (S)
771 5 | 'a' 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
773 ]AT_COND_CASE([[canonical LR]], [['a']],
774 [[$default]])[ reduce using rule 5 (A)
776 Conflict between rule 5 and token 'a' resolved as reduce (%left 'a').
781 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
783 ]AT_COND_CASE([[canonical LR]], [[$end]],
784 [[$default]])[ reduce using rule 1 (S)
789 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
791 ]AT_COND_CASE([[canonical LR]], [[$end]],
792 [[$default]])[ reduce using rule 2 (S)
801 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[19]],
803 'b' shift, and go to state 17
805 ]AT_COND_CASE([[canonical LR]], [[$end]],
806 [[$default]])[ reduce using rule 5 (A)
811 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
813 ]AT_COND_CASE([[canonical LR]], [['a']],
814 [[$default]])[ reduce using rule 4 (A)
819 6 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
821 ]AT_COND_CASE([[canonical LR]], [[$end]],
822 [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]],
831 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
835 state 19]AT_COND_CASE([[canonical LR]], [[
837 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
839 ]AT_COND_CASE([[canonical LR]], [[$end]],
840 [[$default]])[ reduce using rule 4 (A)
848 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]],
851 ]AT_COND_CASE([[canonical LR]], [['b']],
852 [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[
857 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['b']]])[
859 ]AT_COND_CASE([[canonical LR]], [['b']],
860 [[$default]])[ reduce using rule 4 (A)]])])[
866 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
867 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
869 [AT_COND_CASE([[LALR]],
873 AT_TEST_LR_TYPE([[Complex Lane Split]],
875 // Conflict resolution renders state 16 unreachable for canonical LR(1). We
876 // keep it so that the paser table diff is easier to code.
877 %define lr.keep-unreachable-states]],
879 /* Similar to the last test case set but forseeing the S/R conflict from the
880 first state that must be split is becoming difficult. Imagine if B were
881 even more complex. Imagine if A had other RHS's ending in other
898 [['b', 'a', 'a', 'a', 'b']],
911 'a' shift, and go to state 1
912 'b' shift, and go to state 2
913 'c' shift, and go to state 3
923 'a' shift, and go to state 5
933 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[19]])[
945 'a' shift, and go to state 8
955 $end shift, and go to state 11
962 'a' shift, and go to state 12
969 'a' shift, and go to state 13
976 'b' shift, and go to state 14
984 'a' shift, and go to state 15
989 8 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
991 ]AT_COND_CASE([[canonical LR]], [[$end]],
992 [[$default]])[ reduce using rule 8 (c)
997 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
999 ]AT_COND_CASE([[canonical LR]], [[$end]],
1000 [[$default]])[ reduce using rule 3 (S)
1014 6 | . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
1016 ]AT_COND_CASE([[canonical LR]], [['a']],
1017 [[$default]])[ reduce using rule 6 (B)
1021 Conflict between rule 6 and token 'a' resolved as reduce (%left 'a').
1026 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1028 ]AT_COND_CASE([[canonical LR]], [[$end]],
1029 [[$default]])[ reduce using rule 1 (S)
1034 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1036 ]AT_COND_CASE([[canonical LR]], [[$end]],
1037 [[$default]])[ reduce using rule 2 (S)
1047 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
1049 'b' shift, and go to state 18
1051 ]AT_COND_CASE([[canonical LR]], [[$end]],
1052 [[$default]])[ reduce using rule 6 (B)
1054 B go to state ]AT_COND_CASE([[canonical LR]], [[21]], [[17]])[
1059 5 B: 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
1061 ]AT_COND_CASE([[canonical LR]], [['a']],
1062 [[$default]])[ reduce using rule 5 (B)
1067 4 A: 'a' 'a' B .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
1069 ]AT_COND_CASE([[canonical LR]], [['a']],
1070 [[$default]])[ reduce using rule 4 (A)
1075 7 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1077 ]AT_COND_CASE([[canonical LR]], [[$end]],
1078 [[$default]])[ reduce using rule 7 (c)]AT_COND_CASE([[LALR]], [], [[
1085 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[22]],
1089 state 20]AT_COND_CASE([[canonical LR]], [[
1093 $end reduce using rule 5 (B)
1098 4 A: 'a' 'a' B . [$end]
1100 $end reduce using rule 4 (A)
1109 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[23]],
1112 ]AT_COND_CASE([[canonical LR]], [['b']],
1113 [[$default]])[ reduce using rule 6 (B)
1115 B go to state ]AT_COND_CASE([[canonical LR]], [[24
1122 'b' reduce using rule 5 (B)
1127 4 A: 'a' 'a' B . ['b']
1129 'b' reduce using rule 4 (A)]], [[17]])])[
1135 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
1136 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
1138 [AT_COND_CASE([[LALR]],
1142 AT_TEST_LR_TYPE([[Split During Added Lookahead Propagation]],
1143 [[%define lr.keep-unreachable-states]],
1145 /* The partial state chart diagram below is for LALR(1). State 0 is the start
1146 state. States are iterated for successor construction in numerical order.
1147 Transitions are downwards.
1149 State 13 has a R/R conflict that cannot be predicted by Bison's LR(1)
1150 algorithm using annotations alone. That is, when state 11's successor on
1151 'd' is merged with state 5 (which is originally just state 1's successor on
1152 'd'), state 5's successor on 'e' must then be changed because the resulting
1153 lookaheads that propagate to it now make it incompatible with state 8's
1154 successor on 'e'. In other words, state 13 must be split to avoid the
1172 This grammar is designed carefully to make sure that, despite Bison's LR(1)
1173 algorithm's bread-first iteration of transitions to reconstruct states,
1174 state 11's successors are constructed after state 5's and state 8's.
1175 Otherwise (for example, if you remove the first 'c' in each of rules 6 and
1176 7), state 5's successor on 'e' would never be merged with state 8's, so the
1177 split of the resulting state 13 would never need to be performed. */
1191 [['b', 'd', 'e', 'g']],
1194 [AT_COND_CASE([[LALR]],
1195 [[input.y: conflicts: 1 reduce/reduce
1210 'a' shift, and go to state 1
1211 'b' shift, and go to state 2
1212 'c' shift, and go to state 3
1224 'd' shift, and go to state 5
1238 'd' shift, and go to state 8
1246 6 S: 'c' . 'c' A 'g'
1249 'c' shift, and go to state 11
1256 $end shift, and go to state 12
1264 'e' shift, and go to state ]AT_COND_CASE([[LALR]], [[13]],
1265 [[canonical LR]], [[13]],
1273 'f' shift, and go to state 14
1278 2 S: 'a' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1280 ]AT_COND_CASE([[canonical LR]], [[$end]],
1281 [[$default]])[ reduce using rule 2 (S)
1286 5 S: 'b' 'd' . [$end]
1290 'e' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
1293 ]AT_COND_CASE([[canonical LR]], [[$end]],
1294 [[$default]])[ reduce using rule 5 (S)
1301 'f' shift, and go to state 15
1308 'g' shift, and go to state 16
1313 6 S: 'c' 'c' . A 'g'
1318 'd' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]],
1329 $default accept]AT_COND_CASE([[LALR]], [[
1334 8 A: 'd' 'e' . ['f', 'g']
1335 9 B: 'd' 'e' . [$end, 'g']
1337 $end reduce using rule 9 (B)
1338 'g' reduce using rule 8 (A)
1339 'g' [reduce using rule 9 (B)]
1340 $default reduce using rule 8 (A)]], [[
1345 8 A: 'd' 'e' . ['f']
1346 9 B: 'd' 'e' . ]AT_COND_CASE([[canonical LR]], [[[$end]]], [[['g']]])[
1348 ]AT_COND_CASE([[canonical LR]], [[$end]],
1349 [['g' ]])[ reduce using rule 9 (B)
1350 ]AT_COND_CASE([[canonical LR]], [['f' ]],
1351 [[$default]])[ reduce using rule 8 (A)]])[
1356 1 S: 'a' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1358 ]AT_COND_CASE([[canonical LR]], [[$end]],
1359 [[$default]])[ reduce using rule 1 (S)
1364 3 S: 'b' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1366 ]AT_COND_CASE([[canonical LR]], [[$end]],
1367 [[$default]])[ reduce using rule 3 (S)
1372 4 S: 'b' B 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1374 ]AT_COND_CASE([[canonical LR]], [[$end]],
1375 [[$default]])[ reduce using rule 4 (S)
1380 6 S: 'c' 'c' A . 'g'
1382 'g' shift, and go to state 19
1387 7 S: 'c' 'c' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1389 ]AT_COND_CASE([[canonical LR]], [[$end]],
1390 [[$default]])[ reduce using rule 7 (S)
1395 6 S: 'c' 'c' A 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1397 ]AT_COND_CASE([[canonical LR]], [[$end]],
1398 [[$default]])[ reduce using rule 6 (S)]AT_COND_CASE([[LALR]],
1402 state 20]AT_COND_CASE([[canonical LR]], [[
1404 8 A: 'd' 'e' . ['f']
1405 9 B: 'd' 'e' . ['g']
1407 'f' reduce using rule 8 (A)
1408 'g' reduce using rule 9 (B)
1416 'e' shift, and go to state 22
1421 8 A: 'd' 'e' . ['g']
1422 9 B: 'd' 'e' . [$end]
1424 $end reduce using rule 9 (B)
1425 'g' reduce using rule 8 (A)]], [[
1427 8 A: 'd' 'e' . ['f', 'g']
1428 9 B: 'd' 'e' . [$end]
1430 $end reduce using rule 9 (B)
1431 $default reduce using rule 8 (A)]])])[
1437 dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
1438 [AT_COND_CASE([[LALR]], [[1]], [[0]])],
1440 [AT_COND_CASE([[LALR]],
1446 ## ------------------------------- ##
1447 ## %define lr.default-reductions. ##
1448 ## ------------------------------- ##
1450 # AT_TEST_LR_DEFAULT_REDUCTIONS(GRAMMAR, INPUT, TABLES)
1451 # -----------------------------------------------------
1452 m4_define([AT_TEST_LR_DEFAULT_REDUCTIONS],
1454 AT_TEST_TABLES_AND_PARSE([[no %define lr.default-reductions]],
1457 [$1], [$2], [[]], [$3])
1458 AT_TEST_TABLES_AND_PARSE([[%define lr.default-reductions all]],
1460 [[%define lr.default-reductions all]],
1461 [$1], [$2], [[]], [$3])
1462 AT_TEST_TABLES_AND_PARSE([[%define lr.default-reductions consistent]],
1463 [[consistent]], [[]],
1464 [[%define lr.default-reductions consistent]],
1465 [$1], [$2], [[]], [$3])
1466 AT_TEST_TABLES_AND_PARSE([[%define lr.default-reductions accepting]],
1467 [[accepting]], [[]],
1468 [[%define lr.default-reductions accepting]],
1469 [$1], [$2], [[]], [$3])
1472 AT_TEST_LR_DEFAULT_REDUCTIONS([[
1473 /* The start state is consistent and has a shift on 'a' and no reductions.
1474 After pushing the b below, enter an inconsistent state that has a shift and
1475 one reduction with one lookahead. */
1482 /* After shifting this 'a', enter a consistent state that has no shift and 1
1483 reduction with multiple lookaheads. */
1486 /* After the previous reduction, enter an inconsistent state that has no shift
1487 and multiple reductions. The first reduction has more lookaheads than the
1488 second, so the first should always be preferred as the default reduction if
1489 enabled. The second reduction has one lookahead. */
1493 dnl Visit each state mentioned above.
1497 0 $accept: . start $end
1503 'a' shift, and go to state 1
1511 4 a: 'a' .]AT_COND_CASE([[accepting]], [[ [$end, 'a', 'b']
1513 $end reduce using rule 4 (a)
1514 'a' reduce using rule 4 (a)
1515 'b' reduce using rule 4 (a)]], [[
1517 $default reduce using rule 4 (a)]])[
1522 0 $accept: start . $end
1524 $end shift, and go to state 4
1533 6 c: . ['b']]AT_COND_CASE([[all]], [[
1535 'b' reduce using rule 6 (c)
1536 $default reduce using rule 5 (b)]], [[
1538 $end reduce using rule 5 (b)
1539 'a' reduce using rule 5 (b)
1540 'b' reduce using rule 6 (c)]])[
1548 0 $accept: start $end .
1555 1 start: a b . [$end]
1558 'a' shift, and go to state 7
1560 ]AT_COND_CASE([[all]], [[$default]], [[$end]])[ reduce using rule 1 (start)
1567 'b' shift, and go to state 8
1572 2 start: a b 'a' .]AT_COND_CASE([[accepting]], [[ [$end]
1574 $end reduce using rule 2 (start)]], [[
1576 $default reduce using rule 2 (start)]])[
1581 3 start: a c 'b' .]AT_COND_CASE([[accepting]], [[ [$end]
1583 $end reduce using rule 3 (start)]], [[
1585 $default reduce using rule 3 (start)]])[