]> git.saurik.com Git - bison.git/blame_incremental - tests/reduce.at
maint: post-release administrivia
[bison.git] / tests / reduce.at
... / ...
CommitLineData
1# Exercising Bison Grammar Reduction. -*- Autotest -*-
2
3# Copyright (C) 2001-2002, 2007-2013 Free Software Foundation, Inc.
4
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.
9#
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.
14#
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/>.
17
18AT_BANNER([[Grammar Reduction.]])
19
20
21## ------------------- ##
22## Useless Terminals. ##
23## ------------------- ##
24
25AT_SETUP([Useless Terminals])
26
27AT_DATA([[input.y]],
28[[%verbose
29%output "input.c"
30
31%token useless1
32%token useless2
33%token useless3
34%token useless4
35%token useless5
36%token useless6
37%token useless7
38%token useless8
39%token useless9
40
41%token useful
42%%
43exp: useful;
44]])
45
46AT_BISON_CHECK([[input.y]])
47
48AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
49[[Terminals unused in grammar
50 useless1
51 useless2
52 useless3
53 useless4
54 useless5
55 useless6
56 useless7
57 useless8
58 useless9
59]])
60
61AT_CLEANUP
62
63
64
65## ---------------------- ##
66## Useless Nonterminals. ##
67## ---------------------- ##
68
69AT_SETUP([Useless Nonterminals])
70
71AT_DATA([[input.y]],
72[[%verbose
73%output "input.c"
74
75%nterm useless1
76%nterm useless2
77%nterm useless3
78%nterm useless4
79%nterm useless5
80%nterm useless6
81%nterm useless7
82%nterm useless8
83%nterm useless9
84
85%token useful
86%%
87exp: useful;
88]])
89
90AT_BISON_CHECK([[input.y]], 0, [],
91[[input.y: warning: 9 nonterminals useless in grammar [-Wother]
92input.y:4.8-15: warning: nonterminal useless in grammar: useless1 [-Wother]
93input.y:5.8-15: warning: nonterminal useless in grammar: useless2 [-Wother]
94input.y:6.8-15: warning: nonterminal useless in grammar: useless3 [-Wother]
95input.y:7.8-15: warning: nonterminal useless in grammar: useless4 [-Wother]
96input.y:8.8-15: warning: nonterminal useless in grammar: useless5 [-Wother]
97input.y:9.8-15: warning: nonterminal useless in grammar: useless6 [-Wother]
98input.y:10.8-15: warning: nonterminal useless in grammar: useless7 [-Wother]
99input.y:11.8-15: warning: nonterminal useless in grammar: useless8 [-Wother]
100input.y:12.8-15: warning: nonterminal useless in grammar: useless9 [-Wother]
101]])
102
103AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
104[[Nonterminals useless in grammar
105 useless1
106 useless2
107 useless3
108 useless4
109 useless5
110 useless6
111 useless7
112 useless8
113 useless9
114]])
115
116AT_CLEANUP
117
118
119
120## --------------- ##
121## Useless Rules. ##
122## --------------- ##
123
124AT_SETUP([Useless Rules])
125
126AT_KEYWORDS([report])
127
128AT_DATA([[input.y]],
129[[%verbose
130%output "input.c"
131%token useful
132%%
133exp: useful;
134useless1: '1';
135useless2: '2';
136useless3: '3';
137useless4: '4';
138useless5: '5';
139useless6: '6';
140useless7: '7';
141useless8: '8';
142useless9: '9';
143]])
144
145AT_BISON_CHECK([[-fcaret input.y]], 0, [],
146[[input.y: warning: 9 nonterminals useless in grammar [-Wother]
147input.y: warning: 9 rules useless in grammar [-Wother]
148input.y:6.1-8: warning: nonterminal useless in grammar: useless1 [-Wother]
149 useless1: '1';
150 ^^^^^^^^
151input.y:7.1-8: warning: nonterminal useless in grammar: useless2 [-Wother]
152 useless2: '2';
153 ^^^^^^^^
154input.y:8.1-8: warning: nonterminal useless in grammar: useless3 [-Wother]
155 useless3: '3';
156 ^^^^^^^^
157input.y:9.1-8: warning: nonterminal useless in grammar: useless4 [-Wother]
158 useless4: '4';
159 ^^^^^^^^
160input.y:10.1-8: warning: nonterminal useless in grammar: useless5 [-Wother]
161 useless5: '5';
162 ^^^^^^^^
163input.y:11.1-8: warning: nonterminal useless in grammar: useless6 [-Wother]
164 useless6: '6';
165 ^^^^^^^^
166input.y:12.1-8: warning: nonterminal useless in grammar: useless7 [-Wother]
167 useless7: '7';
168 ^^^^^^^^
169input.y:13.1-8: warning: nonterminal useless in grammar: useless8 [-Wother]
170 useless8: '8';
171 ^^^^^^^^
172input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
173 useless9: '9';
174 ^^^^^^^^
175input.y:6.11-13: warning: rule useless in grammar [-Wother]
176 useless1: '1';
177 ^^^
178input.y:7.11-13: warning: rule useless in grammar [-Wother]
179 useless2: '2';
180 ^^^
181input.y:8.11-13: warning: rule useless in grammar [-Wother]
182 useless3: '3';
183 ^^^
184input.y:9.11-13: warning: rule useless in grammar [-Wother]
185 useless4: '4';
186 ^^^
187input.y:10.11-13: warning: rule useless in grammar [-Wother]
188 useless5: '5';
189 ^^^
190input.y:11.11-13: warning: rule useless in grammar [-Wother]
191 useless6: '6';
192 ^^^
193input.y:12.11-13: warning: rule useless in grammar [-Wother]
194 useless7: '7';
195 ^^^
196input.y:13.11-13: warning: rule useless in grammar [-Wother]
197 useless8: '8';
198 ^^^
199input.y:14.11-13: warning: rule useless in grammar [-Wother]
200 useless9: '9';
201 ^^^
202]])
203
204
205AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
206[[Nonterminals useless in grammar
207 useless1
208 useless2
209 useless3
210 useless4
211 useless5
212 useless6
213 useless7
214 useless8
215 useless9
216Terminals unused in grammar
217 '1'
218 '2'
219 '3'
220 '4'
221 '5'
222 '6'
223 '7'
224 '8'
225 '9'
226Rules useless in grammar
227 2 useless1: '1'
228 3 useless2: '2'
229 4 useless3: '3'
230 5 useless4: '4'
231 6 useless5: '5'
232 7 useless6: '6'
233 8 useless7: '7'
234 9 useless8: '8'
235 10 useless9: '9'
236]])
237
238AT_CLEANUP
239
240
241
242## ------------------- ##
243## Reduced Automaton. ##
244## ------------------- ##
245
246# Check that the automaton is that as the for the grammar reduced by
247# hand.
248
249AT_SETUP([Reduced Automaton])
250
251AT_KEYWORDS([report])
252
253# The non reduced grammar.
254# ------------------------
255AT_DATA([[not-reduced.y]],
256[[/* A useless token. */
257%token useless_token
258/* A useful one. */
259%token useful
260%verbose
261%output "not-reduced.c"
262
263%%
264
265exp: useful { /* A useful action. */ }
266 | non_productive { /* A non productive action. */ }
267 ;
268
269not_reachable: useful { /* A not reachable action. */ }
270 ;
271
272non_productive: non_productive useless_token
273 { /* Another non productive action. */ }
274 ;
275%%
276]])
277
278AT_BISON_CHECK([[-fcaret not-reduced.y]], 0, [],
279[[not-reduced.y: warning: 2 nonterminals useless in grammar [-Wother]
280not-reduced.y: warning: 3 rules useless in grammar [-Wother]
281not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
282 not_reachable: useful { /* A not reachable action. */ }
283 ^^^^^^^^^^^^^
284not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive [-Wother]
285 | non_productive { /* A non productive action. */ }
286 ^^^^^^^^^^^^^^
287not-reduced.y:11.6-57: warning: rule useless in grammar [-Wother]
288 | non_productive { /* A non productive action. */ }
289 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
290not-reduced.y:14.16-56: warning: rule useless in grammar [-Wother]
291 not_reachable: useful { /* A not reachable action. */ }
292 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
293not-reduced.y:17.17-18.63: warning: rule useless in grammar [-Wother]
294 non_productive: non_productive useless_token
295 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
296]])
297
298AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
299[[Nonterminals useless in grammar
300 not_reachable
301 non_productive
302Terminals unused in grammar
303 useless_token
304Rules useless in grammar
305 2 exp: non_productive
306 3 not_reachable: useful
307 4 non_productive: non_productive useless_token
308]])
309
310# The reduced grammar.
311# --------------------
312AT_DATA([[reduced.y]],
313[[/* A useless token. */
314%token useless_token
315/* A useful one. */
316%token useful
317%verbose
318%output "reduced.c"
319
320%%
321
322exp: useful { /* A useful action. */ }
323// | non_productive { /* A non productive action. */ } */
324 ;
325
326//not_reachable: useful { /* A not reachable action. */ }
327// ;
328
329//non_productive: non_productive useless_token
330// { /* Another non productive action. */ }
331// ;
332%%
333]])
334
335AT_BISON_CHECK([[reduced.y]])
336
337# Comparing the parsers.
338cp reduced.c expout
339AT_CHECK([sed 's/not-reduced/reduced/g' not-reduced.c], 0, [expout])
340
341AT_CLEANUP
342
343
344
345## ------------------- ##
346## Underivable Rules. ##
347## ------------------- ##
348
349AT_SETUP([Underivable Rules])
350
351AT_KEYWORDS([report])
352
353AT_DATA([[input.y]],
354[[%verbose
355%output "input.c"
356%token useful
357%%
358exp: useful | underivable;
359underivable: indirection;
360indirection: underivable;
361]])
362
363AT_BISON_CHECK([[input.y]], 0, [],
364[[input.y: warning: 2 nonterminals useless in grammar [-Wother]
365input.y: warning: 3 rules useless in grammar [-Wother]
366input.y:5.15-25: warning: nonterminal useless in grammar: underivable [-Wother]
367input.y:6.14-24: warning: nonterminal useless in grammar: indirection [-Wother]
368input.y:5.15-25: warning: rule useless in grammar [-Wother]
369input.y:6.14-24: warning: rule useless in grammar [-Wother]
370input.y:7.14-24: warning: rule useless in grammar [-Wother]
371]])
372
373AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
374[[Nonterminals useless in grammar
375 underivable
376 indirection
377Rules useless in grammar
378 2 exp: underivable
379 3 underivable: indirection
380 4 indirection: underivable
381]])
382
383AT_CLEANUP
384
385
386
387## ---------------- ##
388## Empty Language. ##
389## ---------------- ##
390
391AT_SETUP([Empty Language])
392
393AT_DATA([[input.y]],
394[[%output "input.c"
395%%
396exp: exp;
397]])
398
399AT_BISON_CHECK([[input.y]], 1, [],
400[[input.y: warning: 2 nonterminals useless in grammar [-Wother]
401input.y: warning: 2 rules useless in grammar [-Wother]
402input.y:3.1-3: fatal error: start symbol exp does not derive any sentence
403]])
404
405AT_CLEANUP
406
407
408
409## ----------------- ##
410## %define lr.type. ##
411## ----------------- ##
412
413# AT_TEST_LR_TYPE(DESCRIPTION,
414# DECLS, GRAMMAR, INPUT,
415# BISON-STDERR, TABLES,
416# [OTHER-CHECKS],
417# [PARSER-EXIT-VALUE],
418# [PARSER-STDOUT], [PARSER-STDERR])
419# -------------------------------------------------
420m4_define([AT_TEST_LR_TYPE],
421[
422AT_TEST_TABLES_AND_PARSE([[no %define lr.type: ]$1],
423 [[LALR]], [[]],
424 [$2], m4_shiftn(2, $@))
425AT_TEST_TABLES_AND_PARSE([[%define lr.type lalr: ]$1],
426 [[LALR]], [[]],
427 [[%define lr.type lalr
428]$2],
429 m4_shiftn(2, $@))
430AT_TEST_TABLES_AND_PARSE([[%define lr.type ielr: ]$1],
431 [[IELR]], [[]],
432 [[%define lr.type ielr
433]$2],
434 m4_shiftn(2, $@))
435AT_TEST_TABLES_AND_PARSE([[%define lr.type canonical-lr: ]$1],
436 [[canonical LR]], [[]],
437 [[%define lr.type canonical-lr
438]$2],
439 m4_shiftn(2, $@))
440])
441
442AT_TEST_LR_TYPE([[Single State Split]],
443[[%left 'a'
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]],
447[[
448S: 'a' A 'a' /* rule 1 */
449 | 'b' A 'b' /* rule 2 */
450 | 'c' c /* rule 3 */
451 ;
452
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.
462
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. */
467A: 'a' 'a' /* rule 4 */
468 | 'a' /* rule 5 */
469 ;
470
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. */
475c: 'a' 'b' /* rule 6 */
476 | A /* rule 7 */
477 ;
478]],
479
480dnl INPUT
481[['b', 'a', 'a', 'b']],
482
483dnl BISON-STDERR
484[],
485
486dnl TABLES
487[[State 0
488
489 0 $accept: . S $end
490 1 S: . 'a' A 'a'
491 2 | . 'b' A 'b'
492 3 | . 'c' c
493
494 'a' shift, and go to state 1
495 'b' shift, and go to state 2
496 'c' shift, and go to state 3
497
498 S go to state 4
499
500
501State 1
502
503 1 S: 'a' . A 'a'
504 4 A: . 'a' 'a'
505 5 | . 'a'
506
507 'a' shift, and go to state 5
508
509 A go to state 6
510
511
512State 2
513
514 2 S: 'b' . A 'b'
515 4 A: . 'a' 'a'
516 5 | . 'a'
517
518 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[16]])[
519
520 A go to state 7
521
522
523State 3
524
525 3 S: 'c' . c
526 4 A: . 'a' 'a'
527 5 | . 'a'
528 6 c: . 'a' 'b'
529 7 | . A
530
531 'a' shift, and go to state 8
532
533 A go to state 9
534 c go to state 10
535
536
537State 4
538
539 0 $accept: S . $end
540
541 $end shift, and go to state 11
542
543
544State 5
545
546 4 A: 'a' . 'a'
547 5 | 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
548
549 ]AT_COND_CASE([[canonical LR]], [['a']],
550 [[$default]])[ reduce using rule 5 (A)
551
552 Conflict between rule 5 and token 'a' resolved as reduce (%left 'a').
553
554
555State 6
556
557 1 S: 'a' A . 'a'
558
559 'a' shift, and go to state 13
560
561
562State 7
563
564 2 S: 'b' A . 'b'
565
566 'b' shift, and go to state 14
567
568
569State 8
570
571 4 A: 'a' . 'a'
572 5 | 'a' . [$end]
573 6 c: 'a' . 'b'
574
575 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[17]],
576 [[12]])[
577 'b' shift, and go to state 15
578
579 ]AT_COND_CASE([[canonical LR]], [[$end]],
580 [[$default]])[ reduce using rule 5 (A)
581
582
583State 9
584
585 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
586
587 ]AT_COND_CASE([[canonical LR]], [[$end]],
588 [[$default]])[ reduce using rule 7 (c)
589
590
591State 10
592
593 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
594
595 ]AT_COND_CASE([[canonical LR]], [[$end]],
596 [[$default]])[ reduce using rule 3 (S)
597
598
599State 11
600
601 0 $accept: S $end .
602
603 $default accept
604
605
606State 12
607
608 4 A: 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
609
610 ]AT_COND_CASE([[canonical LR]], [['a']],
611 [[$default]])[ reduce using rule 4 (A)
612
613
614State 13
615
616 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
617
618 ]AT_COND_CASE([[canonical LR]], [[$end]],
619 [[$default]])[ reduce using rule 1 (S)
620
621
622State 14
623
624 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
625
626 ]AT_COND_CASE([[canonical LR]], [[$end]],
627 [[$default]])[ reduce using rule 2 (S)
628
629
630State 15
631
632 6 c: 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
633
634 ]AT_COND_CASE([[canonical LR]], [[$end]],
635 [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]],
636 [[]], [[
637
638
639State 16
640
641 4 A: 'a' . 'a'
642 5 | 'a' . ['b']
643
644 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[18]],
645 [[12]])[
646
647 ]AT_COND_CASE([[canonical LR]], [['b']],
648 [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[
649
650
651State 17
652
653 4 A: 'a' 'a' . [$end]
654
655 $end reduce using rule 4 (A)
656
657
658State 18
659
660 4 A: 'a' 'a' . ['b']
661
662 'b' reduce using rule 4 (A)]])])[
663]],
664
665dnl OTHER-CHECKS
666[],
667
668dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
669[AT_COND_CASE([[LALR]], [[1]], [[0]])],
670[],
671[AT_COND_CASE([[LALR]],
672[[syntax error
673]])])
674
675AT_TEST_LR_TYPE([[Lane Split]],
676[[%left 'a'
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]],
680[[
681/* Similar to the last test case set but two states must be split. */
682S: 'a' A 'a' /* rule 1 */
683 | 'b' A 'b' /* rule 2 */
684 | 'c' c /* rule 3 */
685 ;
686
687A: 'a' 'a' 'a' /* rule 4 */
688 | 'a' 'a' /* rule 5 */
689 ;
690
691c: 'a' 'a' 'b' /* rule 6 */
692 | A /* rule 7 */
693 ;
694]],
695
696dnl INPUT
697[['b', 'a', 'a', 'a', 'b']],
698
699dnl BISON-STDERR
700[],
701
702dnl TABLES
703[[State 0
704
705 0 $accept: . S $end
706 1 S: . 'a' A 'a'
707 2 | . 'b' A 'b'
708 3 | . 'c' c
709
710 'a' shift, and go to state 1
711 'b' shift, and go to state 2
712 'c' shift, and go to state 3
713
714 S go to state 4
715
716
717State 1
718
719 1 S: 'a' . A 'a'
720 4 A: . 'a' 'a' 'a'
721 5 | . 'a' 'a'
722
723 'a' shift, and go to state 5
724
725 A go to state 6
726
727
728State 2
729
730 2 S: 'b' . A 'b'
731 4 A: . 'a' 'a' 'a'
732 5 | . 'a' 'a'
733
734 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[18]])[
735
736 A go to state 7
737
738
739State 3
740
741 3 S: 'c' . c
742 4 A: . 'a' 'a' 'a'
743 5 | . 'a' 'a'
744 6 c: . 'a' 'a' 'b'
745 7 | . A
746
747 'a' shift, and go to state 8
748
749 A go to state 9
750 c go to state 10
751
752
753State 4
754
755 0 $accept: S . $end
756
757 $end shift, and go to state 11
758
759
760State 5
761
762 4 A: 'a' . 'a' 'a'
763 5 | 'a' . 'a'
764
765 'a' shift, and go to state 12
766
767
768State 6
769
770 1 S: 'a' A . 'a'
771
772 'a' shift, and go to state 13
773
774
775State 7
776
777 2 S: 'b' A . 'b'
778
779 'b' shift, and go to state 14
780
781
782State 8
783
784 4 A: 'a' . 'a' 'a'
785 5 | 'a' . 'a'
786 6 c: 'a' . 'a' 'b'
787
788 'a' shift, and go to state 15
789
790
791State 9
792
793 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
794
795 ]AT_COND_CASE([[canonical LR]], [[$end]],
796 [[$default]])[ reduce using rule 7 (c)
797
798
799State 10
800
801 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
802
803 ]AT_COND_CASE([[canonical LR]], [[$end]],
804 [[$default]])[ reduce using rule 3 (S)
805
806
807State 11
808
809 0 $accept: S $end .
810
811 $default accept
812
813
814State 12
815
816 4 A: 'a' 'a' . 'a'
817 5 | 'a' 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
818
819 ]AT_COND_CASE([[canonical LR]], [['a']],
820 [[$default]])[ reduce using rule 5 (A)
821
822 Conflict between rule 5 and token 'a' resolved as reduce (%left 'a').
823
824
825State 13
826
827 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
828
829 ]AT_COND_CASE([[canonical LR]], [[$end]],
830 [[$default]])[ reduce using rule 1 (S)
831
832
833State 14
834
835 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
836
837 ]AT_COND_CASE([[canonical LR]], [[$end]],
838 [[$default]])[ reduce using rule 2 (S)
839
840
841State 15
842
843 4 A: 'a' 'a' . 'a'
844 5 | 'a' 'a' . [$end]
845 6 c: 'a' 'a' . 'b'
846
847 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[19]],
848 [[16]])[
849 'b' shift, and go to state 17
850
851 ]AT_COND_CASE([[canonical LR]], [[$end]],
852 [[$default]])[ reduce using rule 5 (A)
853
854
855State 16
856
857 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
858
859 ]AT_COND_CASE([[canonical LR]], [['a']],
860 [[$default]])[ reduce using rule 4 (A)
861
862
863State 17
864
865 6 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
866
867 ]AT_COND_CASE([[canonical LR]], [[$end]],
868 [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]],
869 [[]], [[
870
871
872State 18
873
874 4 A: 'a' . 'a' 'a'
875 5 | 'a' . 'a'
876
877 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
878 [[19]])[
879
880
881State 19]AT_COND_CASE([[canonical LR]], [[
882
883 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
884
885 ]AT_COND_CASE([[canonical LR]], [[$end]],
886 [[$default]])[ reduce using rule 4 (A)
887
888
889State 20]])[
890
891 4 A: 'a' 'a' . 'a'
892 5 | 'a' 'a' . ['b']
893
894 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]],
895 [[16]])[
896
897 ]AT_COND_CASE([[canonical LR]], [['b']],
898 [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[
899
900
901State 21
902
903 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['b']]])[
904
905 ]AT_COND_CASE([[canonical LR]], [['b']],
906 [[$default]])[ reduce using rule 4 (A)]])])[
907]],
908
909dnl OTHER-CHECKS
910[],
911
912dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
913[AT_COND_CASE([[LALR]], [[1]], [[0]])],
914[],
915[AT_COND_CASE([[LALR]],
916[[syntax error
917]])])
918
919AT_TEST_LR_TYPE([[Complex Lane Split]],
920[[%left 'a'
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]],
924[[
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
928 nonterminals. */
929S: 'a' A 'a'
930 | 'b' A 'b'
931 | 'c' c
932 ;
933A: 'a' 'a' B
934 ;
935B: 'a'
936 | %empty %prec 'a'
937 ;
938c: 'a' 'a' 'b'
939 | A
940 ;
941]],
942
943dnl INPUT
944[['b', 'a', 'a', 'a', 'b']],
945
946dnl BISON-STDERR
947[],
948
949dnl TABLES
950[[State 0
951
952 0 $accept: . S $end
953 1 S: . 'a' A 'a'
954 2 | . 'b' A 'b'
955 3 | . 'c' c
956
957 'a' shift, and go to state 1
958 'b' shift, and go to state 2
959 'c' shift, and go to state 3
960
961 S go to state 4
962
963
964State 1
965
966 1 S: 'a' . A 'a'
967 4 A: . 'a' 'a' B
968
969 'a' shift, and go to state 5
970
971 A go to state 6
972
973
974State 2
975
976 2 S: 'b' . A 'b'
977 4 A: . 'a' 'a' B
978
979 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[19]])[
980
981 A go to state 7
982
983
984State 3
985
986 3 S: 'c' . c
987 4 A: . 'a' 'a' B
988 7 c: . 'a' 'a' 'b'
989 8 | . A
990
991 'a' shift, and go to state 8
992
993 A go to state 9
994 c go to state 10
995
996
997State 4
998
999 0 $accept: S . $end
1000
1001 $end shift, and go to state 11
1002
1003
1004State 5
1005
1006 4 A: 'a' . 'a' B
1007
1008 'a' shift, and go to state 12
1009
1010
1011State 6
1012
1013 1 S: 'a' A . 'a'
1014
1015 'a' shift, and go to state 13
1016
1017
1018State 7
1019
1020 2 S: 'b' A . 'b'
1021
1022 'b' shift, and go to state 14
1023
1024
1025State 8
1026
1027 4 A: 'a' . 'a' B
1028 7 c: 'a' . 'a' 'b'
1029
1030 'a' shift, and go to state 15
1031
1032
1033State 9
1034
1035 8 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1036
1037 ]AT_COND_CASE([[canonical LR]], [[$end]],
1038 [[$default]])[ reduce using rule 8 (c)
1039
1040
1041State 10
1042
1043 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1044
1045 ]AT_COND_CASE([[canonical LR]], [[$end]],
1046 [[$default]])[ reduce using rule 3 (S)
1047
1048
1049State 11
1050
1051 0 $accept: S $end .
1052
1053 $default accept
1054
1055
1056State 12
1057
1058 4 A: 'a' 'a' . B
1059 5 B: . 'a'
1060 6 | . %empty ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
1061
1062 ]AT_COND_CASE([[canonical LR]], [['a']],
1063 [[$default]])[ reduce using rule 6 (B)
1064
1065 B go to state 17
1066
1067 Conflict between rule 6 and token 'a' resolved as reduce (%left 'a').
1068
1069
1070State 13
1071
1072 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1073
1074 ]AT_COND_CASE([[canonical LR]], [[$end]],
1075 [[$default]])[ reduce using rule 1 (S)
1076
1077
1078State 14
1079
1080 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1081
1082 ]AT_COND_CASE([[canonical LR]], [[$end]],
1083 [[$default]])[ reduce using rule 2 (S)
1084
1085
1086State 15
1087
1088 4 A: 'a' 'a' . B
1089 5 B: . 'a'
1090 6 | . %empty [$end]
1091 7 c: 'a' 'a' . 'b'
1092
1093 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
1094 [[16]])[
1095 'b' shift, and go to state 18
1096
1097 ]AT_COND_CASE([[canonical LR]], [[$end]],
1098 [[$default]])[ reduce using rule 6 (B)
1099
1100 B go to state ]AT_COND_CASE([[canonical LR]], [[21]], [[17]])[
1101
1102
1103State 16
1104
1105 5 B: 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
1106
1107 ]AT_COND_CASE([[canonical LR]], [['a']],
1108 [[$default]])[ reduce using rule 5 (B)
1109
1110
1111State 17
1112
1113 4 A: 'a' 'a' B .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
1114
1115 ]AT_COND_CASE([[canonical LR]], [['a']],
1116 [[$default]])[ reduce using rule 4 (A)
1117
1118
1119State 18
1120
1121 7 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1122
1123 ]AT_COND_CASE([[canonical LR]], [[$end]],
1124 [[$default]])[ reduce using rule 7 (c)]AT_COND_CASE([[LALR]], [], [[
1125
1126
1127State 19
1128
1129 4 A: 'a' . 'a' B
1130
1131 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[22]],
1132 [[20]])[
1133
1134
1135State 20]AT_COND_CASE([[canonical LR]], [[
1136
1137 5 B: 'a' . [$end]
1138
1139 $end reduce using rule 5 (B)
1140
1141
1142State 21
1143
1144 4 A: 'a' 'a' B . [$end]
1145
1146 $end reduce using rule 4 (A)
1147
1148
1149State 22]])[
1150
1151 4 A: 'a' 'a' . B
1152 5 B: . 'a'
1153 6 | . %empty ['b']
1154
1155 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[23]],
1156 [[16]])[
1157
1158 ]AT_COND_CASE([[canonical LR]], [['b']],
1159 [[$default]])[ reduce using rule 6 (B)
1160
1161 B go to state ]AT_COND_CASE([[canonical LR]], [[24
1162
1163
1164State 23
1165
1166 5 B: 'a' . ['b']
1167
1168 'b' reduce using rule 5 (B)
1169
1170
1171State 24
1172
1173 4 A: 'a' 'a' B . ['b']
1174
1175 'b' reduce using rule 4 (A)]], [[17]])])[
1176]],
1177
1178dnl OTHER-CHECKS
1179[],
1180
1181dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
1182[AT_COND_CASE([[LALR]], [[1]], [[0]])],
1183[],
1184[AT_COND_CASE([[LALR]],
1185[[syntax error
1186]])])
1187
1188AT_TEST_LR_TYPE([[Split During Added Lookahead Propagation]],
1189[[%define lr.keep-unreachable-state]],
1190[[
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.
1194
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
1201 conflict.
1202
1203 0
1204 / | \
1205 a / c| \ b
1206 1 3 2
1207 | | |
1208 d| |c | d
1209 | 11 |
1210 | | |
1211 \ /d |
1212 5 8
1213 \ |
1214 e \ / e
1215 13
1216 R/R
1217
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. */
1224S: 'a' A 'f'
1225 | 'a' B
1226 | 'b' A 'f'
1227 | 'b' B 'g'
1228 | 'b' 'd'
1229 | 'c' 'c' A 'g'
1230 | 'c' 'c' B
1231 ;
1232A: 'd' 'e' ;
1233B: 'd' 'e' ;
1234]],
1235
1236dnl INPUT
1237[['b', 'd', 'e', 'g']],
1238
1239dnl BISON-STDERR
1240[AT_COND_CASE([[LALR]],
1241[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1242]], [])],
1243
1244dnl TABLES
1245[[State 0
1246
1247 0 $accept: . S $end
1248 1 S: . 'a' A 'f'
1249 2 | . 'a' B
1250 3 | . 'b' A 'f'
1251 4 | . 'b' B 'g'
1252 5 | . 'b' 'd'
1253 6 | . 'c' 'c' A 'g'
1254 7 | . 'c' 'c' B
1255
1256 'a' shift, and go to state 1
1257 'b' shift, and go to state 2
1258 'c' shift, and go to state 3
1259
1260 S go to state 4
1261
1262
1263State 1
1264
1265 1 S: 'a' . A 'f'
1266 2 | 'a' . B
1267 8 A: . 'd' 'e'
1268 9 B: . 'd' 'e'
1269
1270 'd' shift, and go to state 5
1271
1272 A go to state 6
1273 B go to state 7
1274
1275
1276State 2
1277
1278 3 S: 'b' . A 'f'
1279 4 | 'b' . B 'g'
1280 5 | 'b' . 'd'
1281 8 A: . 'd' 'e'
1282 9 B: . 'd' 'e'
1283
1284 'd' shift, and go to state 8
1285
1286 A go to state 9
1287 B go to state 10
1288
1289
1290State 3
1291
1292 6 S: 'c' . 'c' A 'g'
1293 7 | 'c' . 'c' B
1294
1295 'c' shift, and go to state 11
1296
1297
1298State 4
1299
1300 0 $accept: S . $end
1301
1302 $end shift, and go to state 12
1303
1304
1305State 5
1306
1307 8 A: 'd' . 'e'
1308 9 B: 'd' . 'e'
1309
1310 'e' shift, and go to state ]AT_COND_CASE([[LALR]], [[13]],
1311 [[canonical LR]], [[13]],
1312 [[20]])[
1313
1314
1315State 6
1316
1317 1 S: 'a' A . 'f'
1318
1319 'f' shift, and go to state 14
1320
1321
1322State 7
1323
1324 2 S: 'a' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1325
1326 ]AT_COND_CASE([[canonical LR]], [[$end]],
1327 [[$default]])[ reduce using rule 2 (S)
1328
1329
1330State 8
1331
1332 5 S: 'b' 'd' . [$end]
1333 8 A: 'd' . 'e'
1334 9 B: 'd' . 'e'
1335
1336 'e' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
1337 [[13]])[
1338
1339 ]AT_COND_CASE([[canonical LR]], [[$end]],
1340 [[$default]])[ reduce using rule 5 (S)
1341
1342
1343State 9
1344
1345 3 S: 'b' A . 'f'
1346
1347 'f' shift, and go to state 15
1348
1349
1350State 10
1351
1352 4 S: 'b' B . 'g'
1353
1354 'g' shift, and go to state 16
1355
1356
1357State 11
1358
1359 6 S: 'c' 'c' . A 'g'
1360 7 | 'c' 'c' . B
1361 8 A: . 'd' 'e'
1362 9 B: . 'd' 'e'
1363
1364 'd' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]],
1365 [[5]])[
1366
1367 A go to state 17
1368 B go to state 18
1369
1370
1371State 12
1372
1373 0 $accept: S $end .
1374
1375 $default accept]AT_COND_CASE([[LALR]], [[
1376
1377
1378State 13
1379
1380 8 A: 'd' 'e' . ['f', 'g']
1381 9 B: 'd' 'e' . [$end, 'g']
1382
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)]], [[
1387
1388
1389State 13
1390
1391 8 A: 'd' 'e' . ['f']
1392 9 B: 'd' 'e' . ]AT_COND_CASE([[canonical LR]], [[[$end]]], [[['g']]])[
1393
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)]])[
1398
1399
1400State 14
1401
1402 1 S: 'a' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1403
1404 ]AT_COND_CASE([[canonical LR]], [[$end]],
1405 [[$default]])[ reduce using rule 1 (S)
1406
1407
1408State 15
1409
1410 3 S: 'b' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1411
1412 ]AT_COND_CASE([[canonical LR]], [[$end]],
1413 [[$default]])[ reduce using rule 3 (S)
1414
1415
1416State 16
1417
1418 4 S: 'b' B 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1419
1420 ]AT_COND_CASE([[canonical LR]], [[$end]],
1421 [[$default]])[ reduce using rule 4 (S)
1422
1423
1424State 17
1425
1426 6 S: 'c' 'c' A . 'g'
1427
1428 'g' shift, and go to state 19
1429
1430
1431State 18
1432
1433 7 S: 'c' 'c' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1434
1435 ]AT_COND_CASE([[canonical LR]], [[$end]],
1436 [[$default]])[ reduce using rule 7 (S)
1437
1438
1439State 19
1440
1441 6 S: 'c' 'c' A 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1442
1443 ]AT_COND_CASE([[canonical LR]], [[$end]],
1444 [[$default]])[ reduce using rule 6 (S)]AT_COND_CASE([[LALR]],
1445 [[]], [[
1446
1447
1448State 20]AT_COND_CASE([[canonical LR]], [[
1449
1450 8 A: 'd' 'e' . ['f']
1451 9 B: 'd' 'e' . ['g']
1452
1453 'f' reduce using rule 8 (A)
1454 'g' reduce using rule 9 (B)
1455
1456
1457State 21
1458
1459 8 A: 'd' . 'e'
1460 9 B: 'd' . 'e'
1461
1462 'e' shift, and go to state 22
1463
1464
1465State 22
1466
1467 8 A: 'd' 'e' . ['g']
1468 9 B: 'd' 'e' . [$end]
1469
1470 $end reduce using rule 9 (B)
1471 'g' reduce using rule 8 (A)]], [[
1472
1473 8 A: 'd' 'e' . ['f', 'g']
1474 9 B: 'd' 'e' . [$end]
1475
1476 $end reduce using rule 9 (B)
1477 $default reduce using rule 8 (A)]])])[
1478]],
1479
1480dnl OTHER-CHECKS
1481[],
1482
1483dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
1484[AT_COND_CASE([[LALR]], [[1]], [[0]])],
1485[],
1486[AT_COND_CASE([[LALR]],
1487[[syntax error
1488]])])
1489
1490
1491
1492## ------------------------------- ##
1493## %define lr.default-reduction. ##
1494## ------------------------------- ##
1495
1496# AT_TEST_LR_DEFAULT_REDUCTIONS(GRAMMAR, INPUT, TABLES)
1497# -----------------------------------------------------
1498m4_define([AT_TEST_LR_DEFAULT_REDUCTIONS],
1499[
1500AT_TEST_TABLES_AND_PARSE([[no %define lr.default-reduction]],
1501 [[most]], [[]],
1502 [[]],
1503 [$1], [$2], [[]], [$3])
1504AT_TEST_TABLES_AND_PARSE([[%define lr.default-reduction most]],
1505 [[most]], [[]],
1506 [[%define lr.default-reduction most]],
1507 [$1], [$2], [[]], [$3])
1508AT_TEST_TABLES_AND_PARSE([[%define lr.default-reduction consistent]],
1509 [[consistent]], [[]],
1510 [[%define lr.default-reduction consistent]],
1511 [$1], [$2], [[]], [$3])
1512AT_TEST_TABLES_AND_PARSE([[%define lr.default-reduction accepting]],
1513 [[accepting]], [[]],
1514 [[%define lr.default-reduction accepting]],
1515 [$1], [$2], [[]], [$3])
1516])
1517
1518AT_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. */
1522start:
1523 a b
1524 | a b 'a'
1525 | a c 'b'
1526 ;
1527
1528/* After shifting this 'a', enter a consistent state that has no shift and 1
1529 reduction with multiple lookaheads. */
1530a: 'a' ;
1531
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. */
1536b: %empty;
1537c: %empty;
1538]],
1539dnl Visit each state mentioned above.
1540[['a', 'a']],
1541[[State 0
1542
1543 0 $accept: . start $end
1544 1 start: . a b
1545 2 | . a b 'a'
1546 3 | . a c 'b'
1547 4 a: . 'a'
1548
1549 'a' shift, and go to state 1
1550
1551 start go to state 2
1552 a go to state 3
1553
1554
1555State 1
1556
1557 4 a: 'a' .]AT_COND_CASE([[accepting]], [[ [$end, 'a', 'b']
1558
1559 $end reduce using rule 4 (a)
1560 'a' reduce using rule 4 (a)
1561 'b' reduce using rule 4 (a)]], [[
1562
1563 $default reduce using rule 4 (a)]])[
1564
1565
1566State 2
1567
1568 0 $accept: start . $end
1569
1570 $end shift, and go to state 4
1571
1572
1573State 3
1574
1575 1 start: a . b
1576 2 | a . b 'a'
1577 3 | a . c 'b'
1578 5 b: . %empty [$end, 'a']
1579 6 c: . %empty ['b']]AT_COND_CASE([[most]], [[
1580
1581 'b' reduce using rule 6 (c)
1582 $default reduce using rule 5 (b)]], [[
1583
1584 $end reduce using rule 5 (b)
1585 'a' reduce using rule 5 (b)
1586 'b' reduce using rule 6 (c)]])[
1587
1588 b go to state 5
1589 c go to state 6
1590
1591
1592State 4
1593
1594 0 $accept: start $end .
1595
1596 $default accept
1597
1598
1599State 5
1600
1601 1 start: a b . [$end]
1602 2 | a b . 'a'
1603
1604 'a' shift, and go to state 7
1605
1606 ]AT_COND_CASE([[most]], [[$default]],
1607 [[$end]])[ reduce using rule 1 (start)
1608
1609
1610State 6
1611
1612 3 start: a c . 'b'
1613
1614 'b' shift, and go to state 8
1615
1616
1617State 7
1618
1619 2 start: a b 'a' .]AT_COND_CASE([[accepting]], [[ [$end]
1620
1621 $end reduce using rule 2 (start)]], [[
1622
1623 $default reduce using rule 2 (start)]])[
1624
1625
1626State 8
1627
1628 3 start: a c 'b' .]AT_COND_CASE([[accepting]], [[ [$end]
1629
1630 $end reduce using rule 3 (start)]], [[
1631
1632 $default reduce using rule 3 (start)]])[
1633]])