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