]> git.saurik.com Git - bison.git/blob - tests/conflicts.at
705419b95b8c296c685a6664540f3463470f1335
[bison.git] / tests / conflicts.at
1 # Exercising Bison on conflicts. -*- Autotest -*-
2
3 # Copyright (C) 2002-2005, 2007-2010 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
18 AT_BANNER([[Conflicts.]])
19
20
21 ## ---------------- ##
22 ## S/R in initial. ##
23 ## ---------------- ##
24
25 # I once hacked Bison in such a way that it lost its reductions on the
26 # initial state (because it was confusing it with the last state). It
27 # took me a while to strip down my failures to this simple case. So
28 # make sure it finds the s/r conflict below.
29
30 AT_SETUP([S/R in initial])
31
32 AT_DATA([[input.y]],
33 [[%expect 1
34 %%
35 exp: e 'e';
36 e: 'e' | /* Nothing. */;
37 ]])
38
39 AT_BISON_CHECK([-o input.c input.y], 0, [],
40 [[input.y:4.9: warning: rule useless in parser due to conflicts: e: /* empty */
41 ]])
42
43 AT_CLEANUP
44
45
46 ## ------------------- ##
47 ## %nonassoc and eof. ##
48 ## ------------------- ##
49
50 AT_SETUP([%nonassoc and eof])
51
52 AT_DATA_GRAMMAR([input.y],
53 [[
54 %{
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <string.h>
58
59 #define YYERROR_VERBOSE 1
60 static void
61 yyerror (const char *msg)
62 {
63 fprintf (stderr, "%s\n", msg);
64 }
65
66 /* The current argument. */
67 static const char *input;
68
69 static int
70 yylex (void)
71 {
72 static size_t toknum;
73 if (! (toknum <= strlen (input)))
74 abort ();
75 return input[toknum++];
76 }
77
78 %}
79
80 %nonassoc '<' '>'
81
82 %%
83 expr: expr '<' expr
84 | expr '>' expr
85 | '0'
86 ;
87 %%
88 int
89 main (int argc, const char *argv[])
90 {
91 input = argc <= 1 ? "" : argv[1];
92 return yyparse ();
93 }
94 ]])
95
96 # Specify the output files to avoid problems on different file systems.
97 AT_BISON_CHECK([-o input.c input.y])
98 AT_COMPILE([input])
99
100 AT_PARSER_CHECK([./input '0<0'])
101 AT_PARSER_CHECK([./input '0<0<0'], [1], [],
102 [syntax error, unexpected '<'
103 ])
104
105 AT_PARSER_CHECK([./input '0>0'])
106 AT_PARSER_CHECK([./input '0>0>0'], [1], [],
107 [syntax error, unexpected '>'
108 ])
109
110 AT_PARSER_CHECK([./input '0<0>0'], [1], [],
111 [syntax error, unexpected '>'
112 ])
113
114 # We must disable default reductions in inconsistent states in order to
115 # have an explicit list of all expected tokens. (However, unless we use
116 # canonical LR, lookahead sets are merged for different left contexts,
117 # so it is still possible to have extra incorrect tokens in the expected
118 # list. That just doesn't happen to be a problem for this test case.)
119
120 AT_BISON_CHECK([-Dlr.default-reductions=consistent -o input.c input.y])
121 AT_COMPILE([input])
122
123 AT_PARSER_CHECK([./input '0<0'])
124 AT_PARSER_CHECK([./input '0<0<0'], [1], [],
125 [syntax error, unexpected '<', expecting $end
126 ])
127
128 AT_PARSER_CHECK([./input '0>0'])
129 AT_PARSER_CHECK([./input '0>0>0'], [1], [],
130 [syntax error, unexpected '>', expecting $end
131 ])
132
133 AT_PARSER_CHECK([./input '0<0>0'], [1], [],
134 [syntax error, unexpected '>', expecting $end
135 ])
136
137 AT_CLEANUP
138
139
140
141 ## ------------------------------------------- ##
142 ## parse.error=verbose and consistent errors. ##
143 ## ------------------------------------------- ##
144
145 AT_SETUP([[parse.error=verbose and consistent errors]])
146
147 m4_pushdef([AT_CONSISTENT_ERRORS_CHECK], [
148
149 AT_BISON_CHECK([$1[ -o input.c input.y]])
150 AT_COMPILE([[input]])
151
152 m4_pushdef([AT_EXPECTING], [m4_if($3, [ab], [[, expecting 'a' or 'b']],
153 $3, [a], [[, expecting 'a']],
154 $3, [b], [[, expecting 'b']])])
155
156 AT_PARSER_CHECK([[./input]], [[1]], [],
157 [[syntax error, unexpected ]$2[]AT_EXPECTING[
158 ]])
159
160 m4_popdef([AT_EXPECTING])
161
162 ])
163
164 AT_DATA_GRAMMAR([input.y],
165 [[%code {
166 #include <assert.h>
167 #include <stdio.h>
168 int yylex (void);
169 void yyerror (char const *);
170 #define USE(Var)
171 }
172
173 %define parse.error verbose
174
175 // The point isn't to test IELR here, but state merging happens to
176 // complicate the example.
177 %define lr.type ielr
178
179 %nonassoc 'a'
180
181 // If yylval=0 here, then we know that the 'a' destructor is being
182 // invoked incorrectly for the 'b' set in the semantic action below.
183 // All 'a' tokens are returned by yylex, which sets yylval=1.
184 %destructor {
185 if (!$$)
186 fprintf (stderr, "Wrong destructor.\n");
187 } 'a'
188
189 %%
190
191 // The lookahead assigned by the semantic action isn't needed before
192 // either error action is encountered. In a previous version of Bison,
193 // this was a problem as it meant yychar was not translated into yytoken
194 // before either error action. The second error action thus invoked a
195 // destructor that it selected according to the incorrect yytoken. The
196 // first error action would have reported an incorrect unexpected token
197 // except that, due to another bug, the unexpected token is not reported
198 // at all because the error action is the default action in a consistent
199 // state. That bug still needs to be fixed.
200 start: error-reduce consistent-error 'a' { USE ($3); } ;
201
202 error-reduce:
203 'a' 'a' consistent-reduction consistent-error 'a'
204 { USE (($1, $2, $5)); }
205 | 'a' error
206 { USE ($1); }
207 ;
208
209 consistent-reduction: /*empty*/ {
210 assert (yychar == YYEMPTY);
211 yylval = 0;
212 yychar = 'b';
213 } ;
214
215 consistent-error:
216 'a' { USE ($1); }
217 | /*empty*/ %prec 'a'
218 ;
219
220 // Provide another context in which all rules are useful so that this
221 // test case looks a little more realistic.
222 start: 'b' consistent-error 'b' ;
223
224 %%
225
226 int
227 yylex (void)
228 {
229 static char const *input = "aa";
230 yylval = 1;
231 return *input++;
232 }
233
234 void
235 yyerror (char const *msg)
236 {
237 fprintf (stderr, "%s\n", msg);
238 }
239
240 int
241 main (void)
242 {
243 return yyparse ();
244 }
245 ]])
246
247 # See comments in grammar for why this test doesn't succeed.
248 AT_XFAIL_IF([[:]])
249
250 AT_CONSISTENT_ERRORS_CHECK([], [['b']], [[none]])
251 AT_CONSISTENT_ERRORS_CHECK([[-Dlr.default-reductions=consistent]],
252 [['b']], [[none]])
253
254 # Canonical LR doesn't foresee the error for 'a'!
255 AT_CONSISTENT_ERRORS_CHECK([[-Dlr.default-reductions=accepting]],
256 [[$end]], [[a]])
257 AT_CONSISTENT_ERRORS_CHECK([[-Flr.type=canonical-lr]], [[$end]], [[a]])
258
259 m4_popdef([AT_CONSISTENT_ERRORS_CHECK])
260
261 AT_CLEANUP
262
263
264
265 ## ------------------------- ##
266 ## Unresolved SR Conflicts. ##
267 ## ------------------------- ##
268
269 AT_SETUP([Unresolved SR Conflicts])
270
271 AT_KEYWORDS([report])
272
273 AT_DATA([input.y],
274 [[%token NUM OP
275 %%
276 exp: exp OP exp | NUM;
277 ]])
278
279 AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
280 [input.y: conflicts: 1 shift/reduce
281 ])
282
283 # Check the contents of the report.
284 AT_CHECK([cat input.output], [],
285 [[State 5 conflicts: 1 shift/reduce
286
287
288 Grammar
289
290 0 $accept: exp $end
291
292 1 exp: exp OP exp
293 2 | NUM
294
295
296 Terminals, with rules where they appear
297
298 $end (0) 0
299 error (256)
300 NUM (258) 2
301 OP (259) 1
302
303
304 Nonterminals, with rules where they appear
305
306 $accept (5)
307 on left: 0
308 exp (6)
309 on left: 1 2, on right: 0 1
310
311
312 state 0
313
314 0 $accept: . exp $end
315 1 exp: . exp OP exp
316 2 | . NUM
317
318 NUM shift, and go to state 1
319
320 exp go to state 2
321
322
323 state 1
324
325 2 exp: NUM .
326
327 $default reduce using rule 2 (exp)
328
329
330 state 2
331
332 0 $accept: exp . $end
333 1 exp: exp . OP exp
334
335 $end shift, and go to state 3
336 OP shift, and go to state 4
337
338
339 state 3
340
341 0 $accept: exp $end .
342
343 $default accept
344
345
346 state 4
347
348 1 exp: . exp OP exp
349 1 | exp OP . exp
350 2 | . NUM
351
352 NUM shift, and go to state 1
353
354 exp go to state 5
355
356
357 state 5
358
359 1 exp: exp . OP exp
360 1 | exp OP exp . [$end, OP]
361
362 OP shift, and go to state 4
363
364 OP [reduce using rule 1 (exp)]
365 $default reduce using rule 1 (exp)
366 ]])
367
368 AT_CLEANUP
369
370
371
372 ## ----------------------- ##
373 ## Resolved SR Conflicts. ##
374 ## ----------------------- ##
375
376 AT_SETUP([Resolved SR Conflicts])
377
378 AT_KEYWORDS([report])
379
380 AT_DATA([input.y],
381 [[%token NUM OP
382 %left OP
383 %%
384 exp: exp OP exp | NUM;
385 ]])
386
387 AT_BISON_CHECK([-o input.c --report=all input.y])
388
389 # Check the contents of the report.
390 AT_CHECK([cat input.output], [],
391 [[Grammar
392
393 0 $accept: exp $end
394
395 1 exp: exp OP exp
396 2 | NUM
397
398
399 Terminals, with rules where they appear
400
401 $end (0) 0
402 error (256)
403 NUM (258) 2
404 OP (259) 1
405
406
407 Nonterminals, with rules where they appear
408
409 $accept (5)
410 on left: 0
411 exp (6)
412 on left: 1 2, on right: 0 1
413
414
415 state 0
416
417 0 $accept: . exp $end
418 1 exp: . exp OP exp
419 2 | . NUM
420
421 NUM shift, and go to state 1
422
423 exp go to state 2
424
425
426 state 1
427
428 2 exp: NUM .
429
430 $default reduce using rule 2 (exp)
431
432
433 state 2
434
435 0 $accept: exp . $end
436 1 exp: exp . OP exp
437
438 $end shift, and go to state 3
439 OP shift, and go to state 4
440
441
442 state 3
443
444 0 $accept: exp $end .
445
446 $default accept
447
448
449 state 4
450
451 1 exp: . exp OP exp
452 1 | exp OP . exp
453 2 | . NUM
454
455 NUM shift, and go to state 1
456
457 exp go to state 5
458
459
460 state 5
461
462 1 exp: exp . OP exp
463 1 | exp OP exp . [$end, OP]
464
465 $default reduce using rule 1 (exp)
466
467 Conflict between rule 1 and token OP resolved as reduce (%left OP).
468 ]])
469
470 AT_CLEANUP
471
472
473 ## ---------------------- ##
474 ## %precedence suffices. ##
475 ## ---------------------- ##
476
477 AT_SETUP([%precedence suffices])
478
479 AT_DATA([input.y],
480 [[%precedence "then"
481 %precedence "else"
482 %%
483 stmt:
484 "if" cond "then" stmt
485 | "if" cond "then" stmt "else" stmt
486 | "stmt"
487 ;
488
489 cond:
490 "exp"
491 ;
492 ]])
493
494 AT_BISON_CHECK([-o input.c input.y])
495
496 AT_CLEANUP
497
498
499 ## ------------------------------ ##
500 ## %precedence does not suffice. ##
501 ## ------------------------------ ##
502
503 AT_SETUP([%precedence does not suffice])
504
505 AT_DATA([input.y],
506 [[%precedence "then"
507 %precedence "else"
508 %%
509 stmt:
510 "if" cond "then" stmt
511 | "if" cond "then" stmt "else" stmt
512 | "stmt"
513 ;
514
515 cond:
516 "exp"
517 | cond "then" cond
518 ;
519 ]])
520
521 AT_BISON_CHECK([-o input.c input.y], 0, [],
522 [[input.y: conflicts: 1 shift/reduce
523 input.y:12.3-18: warning: rule useless in parser due to conflicts: cond: cond "then" cond
524 ]])
525
526 AT_CLEANUP
527
528
529 ## -------------------------------- ##
530 ## Defaulted Conflicted Reduction. ##
531 ## -------------------------------- ##
532
533 # When there are RR conflicts, some rules are disabled. Usually it is
534 # simply displayed as:
535 #
536 # $end reduce using rule 3 (num)
537 # $end [reduce using rule 4 (id)]
538 #
539 # But when `reduce 3' is the default action, we'd produce:
540 #
541 # $end [reduce using rule 4 (id)]
542 # $default reduce using rule 3 (num)
543 #
544 # In this precise case (a reduction is masked by the default
545 # reduction), we make the `reduce 3' explicit:
546 #
547 # $end reduce using rule 3 (num)
548 # $end [reduce using rule 4 (id)]
549 # $default reduce using rule 3 (num)
550 #
551 # Maybe that's not the best display, but then, please propose something
552 # else.
553
554 AT_SETUP([Defaulted Conflicted Reduction])
555 AT_KEYWORDS([report])
556
557 AT_DATA([input.y],
558 [[%%
559 exp: num | id;
560 num: '0';
561 id : '0';
562 %%
563 ]])
564
565 AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
566 [[input.y: conflicts: 1 reduce/reduce
567 input.y:4.6-8: warning: rule useless in parser due to conflicts: id: '0'
568 ]])
569
570 # Check the contents of the report.
571 AT_CHECK([cat input.output], [],
572 [[Rules useless in parser due to conflicts
573
574 4 id: '0'
575
576
577 State 1 conflicts: 1 reduce/reduce
578
579
580 Grammar
581
582 0 $accept: exp $end
583
584 1 exp: num
585 2 | id
586
587 3 num: '0'
588
589 4 id: '0'
590
591
592 Terminals, with rules where they appear
593
594 $end (0) 0
595 '0' (48) 3 4
596 error (256)
597
598
599 Nonterminals, with rules where they appear
600
601 $accept (4)
602 on left: 0
603 exp (5)
604 on left: 1 2, on right: 0
605 num (6)
606 on left: 3, on right: 1
607 id (7)
608 on left: 4, on right: 2
609
610
611 state 0
612
613 0 $accept: . exp $end
614 1 exp: . num
615 2 | . id
616 3 num: . '0'
617 4 id: . '0'
618
619 '0' shift, and go to state 1
620
621 exp go to state 2
622 num go to state 3
623 id go to state 4
624
625
626 state 1
627
628 3 num: '0' . [$end]
629 4 id: '0' . [$end]
630
631 $end reduce using rule 3 (num)
632 $end [reduce using rule 4 (id)]
633 $default reduce using rule 3 (num)
634
635
636 state 2
637
638 0 $accept: exp . $end
639
640 $end shift, and go to state 5
641
642
643 state 3
644
645 1 exp: num .
646
647 $default reduce using rule 1 (exp)
648
649
650 state 4
651
652 2 exp: id .
653
654 $default reduce using rule 2 (exp)
655
656
657 state 5
658
659 0 $accept: exp $end .
660
661 $default accept
662 ]])
663
664 AT_CLEANUP
665
666
667
668
669 ## -------------------- ##
670 ## %expect not enough. ##
671 ## -------------------- ##
672
673 AT_SETUP([%expect not enough])
674
675 AT_DATA([input.y],
676 [[%token NUM OP
677 %expect 0
678 %%
679 exp: exp OP exp | NUM;
680 ]])
681
682 AT_BISON_CHECK([-o input.c input.y], 1, [],
683 [input.y: conflicts: 1 shift/reduce
684 input.y: expected 0 shift/reduce conflicts
685 ])
686 AT_CLEANUP
687
688
689 ## --------------- ##
690 ## %expect right. ##
691 ## --------------- ##
692
693 AT_SETUP([%expect right])
694
695 AT_DATA([input.y],
696 [[%token NUM OP
697 %expect 1
698 %%
699 exp: exp OP exp | NUM;
700 ]])
701
702 AT_BISON_CHECK([-o input.c input.y])
703 AT_CLEANUP
704
705
706 ## ------------------ ##
707 ## %expect too much. ##
708 ## ------------------ ##
709
710 AT_SETUP([%expect too much])
711
712 AT_DATA([input.y],
713 [[%token NUM OP
714 %expect 2
715 %%
716 exp: exp OP exp | NUM;
717 ]])
718
719 AT_BISON_CHECK([-o input.c input.y], 1, [],
720 [input.y: conflicts: 1 shift/reduce
721 input.y: expected 2 shift/reduce conflicts
722 ])
723 AT_CLEANUP
724
725
726 ## ------------------------------- ##
727 ## %expect with reduce conflicts. ##
728 ## ------------------------------- ##
729
730 AT_SETUP([%expect with reduce conflicts])
731
732 AT_DATA([input.y],
733 [[%expect 0
734 %%
735 program: a 'a' | a a;
736 a: 'a';
737 ]])
738
739 AT_BISON_CHECK([-o input.c input.y], 1, [],
740 [input.y: conflicts: 1 reduce/reduce
741 input.y: expected 0 reduce/reduce conflicts
742 ])
743 AT_CLEANUP
744
745
746 ## ------------------------- ##
747 ## %prec with user strings. ##
748 ## ------------------------- ##
749
750 AT_SETUP([%prec with user string])
751
752 AT_DATA([[input.y]],
753 [[%%
754 exp:
755 "foo" %prec "foo"
756 ;
757 ]])
758
759 AT_BISON_CHECK([-o input.c input.y])
760 AT_CLEANUP
761
762
763 ## -------------------------------- ##
764 ## %no-default-prec without %prec. ##
765 ## -------------------------------- ##
766
767 AT_SETUP([%no-default-prec without %prec])
768
769 AT_DATA([[input.y]],
770 [[%left '+'
771 %left '*'
772
773 %%
774
775 %no-default-prec;
776
777 e: e '+' e
778 | e '*' e
779 | '0'
780 ;
781 ]])
782
783 AT_BISON_CHECK([-o input.c input.y], 0, [],
784 [[input.y: conflicts: 4 shift/reduce
785 ]])
786 AT_CLEANUP
787
788
789 ## ----------------------------- ##
790 ## %no-default-prec with %prec. ##
791 ## ----------------------------- ##
792
793 AT_SETUP([%no-default-prec with %prec])
794
795 AT_DATA([[input.y]],
796 [[%left '+'
797 %left '*'
798
799 %%
800
801 %no-default-prec;
802
803 e: e '+' e %prec '+'
804 | e '*' e %prec '*'
805 | '0'
806 ;
807 ]])
808
809 AT_BISON_CHECK([-o input.c input.y])
810 AT_CLEANUP
811
812
813 ## --------------- ##
814 ## %default-prec. ##
815 ## --------------- ##
816
817 AT_SETUP([%default-prec])
818
819 AT_DATA([[input.y]],
820 [[%left '+'
821 %left '*'
822
823 %%
824
825 %default-prec;
826
827 e: e '+' e
828 | e '*' e
829 | '0'
830 ;
831 ]])
832
833 AT_BISON_CHECK([-o input.c input.y])
834 AT_CLEANUP
835
836
837 ## ---------------------------------------------- ##
838 ## Unreachable States After Conflict Resolution. ##
839 ## ---------------------------------------------- ##
840
841 AT_SETUP([[Unreachable States After Conflict Resolution]])
842
843 # If conflict resolution makes states unreachable, remove those states, report
844 # rules that are then unused, and don't report conflicts in those states. Test
845 # what happens when a nonterminal becomes useless as a result of state removal
846 # since that causes lalr.o's goto map to be rewritten.
847
848 AT_DATA([[input.y]],
849 [[%output "input.c"
850 %left 'a'
851
852 %%
853
854 start: resolved_conflict 'a' reported_conflicts 'a' ;
855
856 /* S/R conflict resolved as reduce, so the state with item
857 * (resolved_conflict: 'a' . unreachable1) and all it transition successors are
858 * unreachable, and the associated production is useless. */
859 resolved_conflict:
860 'a' unreachable1
861 | %prec 'a'
862 ;
863
864 /* S/R conflict that need not be reported since it is unreachable because of
865 * the previous conflict resolution. Nonterminal unreachable1 and all its
866 * productions are useless. */
867 unreachable1:
868 'a' unreachable2
869 |
870 ;
871
872 /* Likewise for a R/R conflict and nonterminal unreachable2. */
873 unreachable2: | ;
874
875 /* Make sure remaining S/R and R/R conflicts are still reported correctly even
876 * when their states are renumbered due to state removal. */
877 reported_conflicts:
878 'a'
879 | 'a'
880 |
881 ;
882
883 ]])
884
885 AT_BISON_CHECK([[--report=all input.y]], 0, [],
886 [[input.y: conflicts: 1 shift/reduce, 1 reduce/reduce
887 input.y:12.5-20: warning: rule useless in parser due to conflicts: resolved_conflict: 'a' unreachable1
888 input.y:20.5-20: warning: rule useless in parser due to conflicts: unreachable1: 'a' unreachable2
889 input.y:21.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */
890 input.y:25.13: warning: rule useless in parser due to conflicts: unreachable2: /* empty */
891 input.y:25.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */
892 input.y:31.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a'
893 input.y:32.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */
894 ]])
895
896 AT_CHECK([[cat input.output]], 0,
897 [[Rules useless in parser due to conflicts
898
899 2 resolved_conflict: 'a' unreachable1
900
901 4 unreachable1: 'a' unreachable2
902 5 | /* empty */
903
904 6 unreachable2: /* empty */
905 7 | /* empty */
906
907 9 reported_conflicts: 'a'
908 10 | /* empty */
909
910
911 State 4 conflicts: 1 shift/reduce
912 State 5 conflicts: 1 reduce/reduce
913
914
915 Grammar
916
917 0 $accept: start $end
918
919 1 start: resolved_conflict 'a' reported_conflicts 'a'
920
921 2 resolved_conflict: 'a' unreachable1
922 3 | /* empty */
923
924 4 unreachable1: 'a' unreachable2
925 5 | /* empty */
926
927 6 unreachable2: /* empty */
928 7 | /* empty */
929
930 8 reported_conflicts: 'a'
931 9 | 'a'
932 10 | /* empty */
933
934
935 Terminals, with rules where they appear
936
937 $end (0) 0
938 'a' (97) 1 2 4 8 9
939 error (256)
940
941
942 Nonterminals, with rules where they appear
943
944 $accept (4)
945 on left: 0
946 start (5)
947 on left: 1, on right: 0
948 resolved_conflict (6)
949 on left: 2 3, on right: 1
950 unreachable1 (7)
951 on left: 4 5, on right: 2
952 unreachable2 (8)
953 on left: 6 7, on right: 4
954 reported_conflicts (9)
955 on left: 8 9 10, on right: 1
956
957
958 state 0
959
960 0 $accept: . start $end
961 1 start: . resolved_conflict 'a' reported_conflicts 'a'
962 2 resolved_conflict: . 'a' unreachable1
963 3 | . ['a']
964
965 $default reduce using rule 3 (resolved_conflict)
966
967 start go to state 1
968 resolved_conflict go to state 2
969
970 Conflict between rule 3 and token 'a' resolved as reduce (%left 'a').
971
972
973 state 1
974
975 0 $accept: start . $end
976
977 $end shift, and go to state 3
978
979
980 state 2
981
982 1 start: resolved_conflict . 'a' reported_conflicts 'a'
983
984 'a' shift, and go to state 4
985
986
987 state 3
988
989 0 $accept: start $end .
990
991 $default accept
992
993
994 state 4
995
996 1 start: resolved_conflict 'a' . reported_conflicts 'a'
997 8 reported_conflicts: . 'a'
998 9 | . 'a'
999 10 | . ['a']
1000
1001 'a' shift, and go to state 5
1002
1003 'a' [reduce using rule 10 (reported_conflicts)]
1004
1005 reported_conflicts go to state 6
1006
1007
1008 state 5
1009
1010 8 reported_conflicts: 'a' . ['a']
1011 9 | 'a' . ['a']
1012
1013 'a' reduce using rule 8 (reported_conflicts)
1014 'a' [reduce using rule 9 (reported_conflicts)]
1015 $default reduce using rule 8 (reported_conflicts)
1016
1017
1018 state 6
1019
1020 1 start: resolved_conflict 'a' reported_conflicts . 'a'
1021
1022 'a' shift, and go to state 7
1023
1024
1025 state 7
1026
1027 1 start: resolved_conflict 'a' reported_conflicts 'a' .
1028
1029 $default reduce using rule 1 (start)
1030 ]])
1031
1032 AT_DATA([[input-keep.y]],
1033 [[%define lr.keep-unreachable-states
1034 ]])
1035 AT_CHECK([[cat input.y >> input-keep.y]])
1036
1037 AT_BISON_CHECK([[input-keep.y]], 0, [],
1038 [[input-keep.y: conflicts: 2 shift/reduce, 2 reduce/reduce
1039 input-keep.y:22.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */
1040 input-keep.y:26.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */
1041 input-keep.y:32.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a'
1042 input-keep.y:33.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */
1043 ]])
1044
1045 AT_CLEANUP
1046
1047
1048 ## ------------------------------------------------------------ ##
1049 ## Solved conflicts report for multiple reductions in a state. ##
1050 ## ------------------------------------------------------------ ##
1051
1052 AT_SETUP([[Solved conflicts report for multiple reductions in a state]])
1053
1054 # Used to lose earlier solved conflict messages even within a single S/R/R.
1055
1056 AT_DATA([[input.y]],
1057 [[%left 'a'
1058 %right 'b'
1059 %right 'c'
1060 %right 'd'
1061 %%
1062 start:
1063 'a'
1064 | empty_a 'a'
1065 | 'b'
1066 | empty_b 'b'
1067 | 'c'
1068 | empty_c1 'c'
1069 | empty_c2 'c'
1070 | empty_c3 'c'
1071 ;
1072 empty_a: %prec 'a' ;
1073 empty_b: %prec 'b' ;
1074 empty_c1: %prec 'c' ;
1075 empty_c2: %prec 'c' ;
1076 empty_c3: %prec 'd' ;
1077 ]])
1078 AT_BISON_CHECK([[--report=all -o input.c input.y]], 0, [], [ignore])
1079 AT_CHECK([[cat input.output | sed -n '/^state 0$/,/^state 1$/p']], 0,
1080 [[state 0
1081
1082 0 $accept: . start $end
1083 1 start: . 'a'
1084 2 | . empty_a 'a'
1085 3 | . 'b'
1086 4 | . empty_b 'b'
1087 5 | . 'c'
1088 6 | . empty_c1 'c'
1089 7 | . empty_c2 'c'
1090 8 | . empty_c3 'c'
1091 9 empty_a: . ['a']
1092 10 empty_b: . []
1093 11 empty_c1: . []
1094 12 empty_c2: . []
1095 13 empty_c3: . ['c']
1096
1097 'b' shift, and go to state 1
1098
1099 'c' reduce using rule 13 (empty_c3)
1100 $default reduce using rule 9 (empty_a)
1101
1102 start go to state 2
1103 empty_a go to state 3
1104 empty_b go to state 4
1105 empty_c1 go to state 5
1106 empty_c2 go to state 6
1107 empty_c3 go to state 7
1108
1109 Conflict between rule 9 and token 'a' resolved as reduce (%left 'a').
1110 Conflict between rule 10 and token 'b' resolved as shift (%right 'b').
1111 Conflict between rule 11 and token 'c' resolved as shift (%right 'c').
1112 Conflict between rule 12 and token 'c' resolved as shift (%right 'c').
1113 Conflict between rule 13 and token 'c' resolved as reduce ('c' < 'd').
1114
1115
1116 state 1
1117 ]])
1118
1119 AT_CLEANUP
1120
1121
1122 ## ------------------------------------------------------------ ##
1123 ## %nonassoc error actions for multiple reductions in a state. ##
1124 ## ------------------------------------------------------------ ##
1125
1126 # Used to abort when trying to resolve conflicts as %nonassoc error actions for
1127 # multiple reductions in a state.
1128
1129 # For a %nonassoc error action token, used to print the first remaining
1130 # reduction on that token without brackets.
1131
1132 AT_SETUP([[%nonassoc error actions for multiple reductions in a state]])
1133
1134 AT_DATA([[input.y]],
1135 [[%nonassoc 'a' 'b' 'c'
1136 %%
1137 start:
1138 'a'
1139 | empty_a 'a'
1140 | 'b'
1141 | empty_b 'b'
1142 | 'c'
1143 | empty_c1 'c'
1144 | empty_c2 'c'
1145 | empty_c3 'c'
1146 ;
1147 empty_a: %prec 'a' ;
1148 empty_b: %prec 'b' ;
1149 empty_c1: %prec 'c' ;
1150 empty_c2: %prec 'c' ;
1151 empty_c3: %prec 'c' ;
1152 ]])
1153
1154 AT_BISON_CHECK([[--report=all -o input.c input.y]], 0, [], [ignore])
1155 AT_CHECK([[cat input.output | sed -n '/^state 0$/,/^state 1$/p']], 0,
1156 [[state 0
1157
1158 0 $accept: . start $end
1159 1 start: . 'a'
1160 2 | . empty_a 'a'
1161 3 | . 'b'
1162 4 | . empty_b 'b'
1163 5 | . 'c'
1164 6 | . empty_c1 'c'
1165 7 | . empty_c2 'c'
1166 8 | . empty_c3 'c'
1167 9 empty_a: . []
1168 10 empty_b: . []
1169 11 empty_c1: . []
1170 12 empty_c2: . ['c']
1171 13 empty_c3: . ['c']
1172
1173 'a' error (nonassociative)
1174 'b' error (nonassociative)
1175 'c' error (nonassociative)
1176
1177 'c' [reduce using rule 12 (empty_c2)]
1178 'c' [reduce using rule 13 (empty_c3)]
1179
1180 start go to state 1
1181 empty_a go to state 2
1182 empty_b go to state 3
1183 empty_c1 go to state 4
1184 empty_c2 go to state 5
1185 empty_c3 go to state 6
1186
1187 Conflict between rule 9 and token 'a' resolved as an error (%nonassoc 'a').
1188 Conflict between rule 10 and token 'b' resolved as an error (%nonassoc 'b').
1189 Conflict between rule 11 and token 'c' resolved as an error (%nonassoc 'c').
1190
1191
1192 state 1
1193 ]])
1194 AT_CLEANUP