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