]> git.saurik.com Git - bison.git/blame_incremental - tests/conflicts.at
Code cleanup.
[bison.git] / tests / conflicts.at
... / ...
CommitLineData
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
18AT_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
30AT_SETUP([S/R in initial])
31
32AT_DATA([[input.y]],
33[[%expect 1
34%%
35exp: e 'e';
36e: 'e' | /* Nothing. */;
37]])
38
39AT_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
43AT_CLEANUP
44
45
46## ------------------- ##
47## %nonassoc and eof. ##
48## ------------------- ##
49
50AT_SETUP([%nonassoc and eof])
51
52AT_DATA_GRAMMAR([input.y],
53[[
54%{
55#include <stdio.h>
56#include <stdlib.h>
57#include <string.h>
58
59#define YYERROR_VERBOSE 1
60static void
61yyerror (const char *msg)
62{
63 fprintf (stderr, "%s\n", msg);
64}
65
66/* The current argument. */
67static const char *input;
68
69static int
70yylex (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%%
83expr: expr '<' expr
84 | expr '>' expr
85 | '0'
86 ;
87%%
88int
89main (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.
97AT_BISON_CHECK([-o input.c input.y])
98AT_COMPILE([input])
99
100AT_PARSER_CHECK([./input '0<0'])
101AT_PARSER_CHECK([./input '0<0<0'], [1], [],
102 [syntax error, unexpected '<'
103])
104
105AT_PARSER_CHECK([./input '0>0'])
106AT_PARSER_CHECK([./input '0>0>0'], [1], [],
107 [syntax error, unexpected '>'
108])
109
110AT_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
120AT_BISON_CHECK([-Dlr.default-reductions=consistent -o input.c input.y])
121AT_COMPILE([input])
122
123AT_PARSER_CHECK([./input '0<0'])
124AT_PARSER_CHECK([./input '0<0<0'], [1], [],
125 [syntax error, unexpected '<', expecting $end
126])
127
128AT_PARSER_CHECK([./input '0>0'])
129AT_PARSER_CHECK([./input '0>0>0'], [1], [],
130 [syntax error, unexpected '>', expecting $end
131])
132
133AT_PARSER_CHECK([./input '0<0>0'], [1], [],
134 [syntax error, unexpected '>', expecting $end
135])
136
137AT_CLEANUP
138
139
140
141## ------------------------------------------- ##
142## parse.error=verbose and consistent errors. ##
143## ------------------------------------------- ##
144
145AT_SETUP([[parse.error=verbose and consistent errors]])
146
147m4_pushdef([AT_CONSISTENT_ERRORS_CHECK], [
148
149AT_BISON_CHECK([$1[ -o input.c input.y]])
150AT_COMPILE([[input]])
151
152m4_pushdef([AT_EXPECTING], [m4_if($3, [ab], [[, expecting 'a' or 'b']],
153 $3, [a], [[, expecting 'a']],
154 $3, [b], [[, expecting 'b']])])
155
156AT_PARSER_CHECK([[./input]], [[1]], [],
157[[syntax error, unexpected ]$2[]AT_EXPECTING[
158]])
159
160m4_popdef([AT_EXPECTING])
161
162])
163
164AT_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.
200start: error-reduce consistent-error 'a' { USE ($3); } ;
201
202error-reduce:
203 'a' 'a' consistent-reduction consistent-error 'a'
204 { USE (($1, $2, $5)); }
205| 'a' error
206 { USE ($1); }
207;
208
209consistent-reduction: /*empty*/ {
210 assert (yychar == YYEMPTY);
211 yylval = 0;
212 yychar = 'b';
213} ;
214
215consistent-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.
222start: 'b' consistent-error 'b' ;
223
224%%
225
226int
227yylex (void)
228{
229 static char const *input = "aa";
230 yylval = 1;
231 return *input++;
232}
233
234void
235yyerror (char const *msg)
236{
237 fprintf (stderr, "%s\n", msg);
238}
239
240int
241main (void)
242{
243 return yyparse ();
244}
245]])
246
247# See comments in grammar for why this test doesn't succeed.
248AT_XFAIL_IF([[:]])
249
250AT_CONSISTENT_ERRORS_CHECK([], [['b']], [[none]])
251AT_CONSISTENT_ERRORS_CHECK([[-Dlr.default-reductions=consistent]],
252 [['b']], [[none]])
253
254# Canonical LR doesn't foresee the error for 'a'!
255AT_CONSISTENT_ERRORS_CHECK([[-Dlr.default-reductions=accepting]],
256 [[$end]], [[a]])
257AT_CONSISTENT_ERRORS_CHECK([[-Flr.type=canonical-lr]], [[$end]], [[a]])
258
259m4_popdef([AT_CONSISTENT_ERRORS_CHECK])
260
261AT_CLEANUP
262
263
264
265## ------------------------- ##
266## Unresolved SR Conflicts. ##
267## ------------------------- ##
268
269AT_SETUP([Unresolved SR Conflicts])
270
271AT_KEYWORDS([report])
272
273AT_DATA([input.y],
274[[%token NUM OP
275%%
276exp: exp OP exp | NUM;
277]])
278
279AT_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.
284AT_CHECK([cat input.output], [],
285[[State 5 conflicts: 1 shift/reduce
286
287
288Grammar
289
290 0 $accept: exp $end
291
292 1 exp: exp OP exp
293 2 | NUM
294
295
296Terminals, with rules where they appear
297
298$end (0) 0
299error (256)
300NUM (258) 2
301OP (259) 1
302
303
304Nonterminals, with rules where they appear
305
306$accept (5)
307 on left: 0
308exp (6)
309 on left: 1 2, on right: 0 1
310
311
312state 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
323state 1
324
325 2 exp: NUM .
326
327 $default reduce using rule 2 (exp)
328
329
330state 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
339state 3
340
341 0 $accept: exp $end .
342
343 $default accept
344
345
346state 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
357state 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
368AT_CLEANUP
369
370
371
372## ----------------------- ##
373## Resolved SR Conflicts. ##
374## ----------------------- ##
375
376AT_SETUP([Resolved SR Conflicts])
377
378AT_KEYWORDS([report])
379
380AT_DATA([input.y],
381[[%token NUM OP
382%left OP
383%%
384exp: exp OP exp | NUM;
385]])
386
387AT_BISON_CHECK([-o input.c --report=all input.y])
388
389# Check the contents of the report.
390AT_CHECK([cat input.output], [],
391[[Grammar
392
393 0 $accept: exp $end
394
395 1 exp: exp OP exp
396 2 | NUM
397
398
399Terminals, with rules where they appear
400
401$end (0) 0
402error (256)
403NUM (258) 2
404OP (259) 1
405
406
407Nonterminals, with rules where they appear
408
409$accept (5)
410 on left: 0
411exp (6)
412 on left: 1 2, on right: 0 1
413
414
415state 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
426state 1
427
428 2 exp: NUM .
429
430 $default reduce using rule 2 (exp)
431
432
433state 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
442state 3
443
444 0 $accept: exp $end .
445
446 $default accept
447
448
449state 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
460state 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
470AT_CLEANUP
471
472
473## ---------------------- ##
474## %precedence suffices. ##
475## ---------------------- ##
476
477AT_SETUP([%precedence suffices])
478
479AT_DATA([input.y],
480[[%precedence "then"
481%precedence "else"
482%%
483stmt:
484 "if" cond "then" stmt
485| "if" cond "then" stmt "else" stmt
486| "stmt"
487;
488
489cond:
490 "exp"
491;
492]])
493
494AT_BISON_CHECK([-o input.c input.y])
495
496AT_CLEANUP
497
498
499## ------------------------------ ##
500## %precedence does not suffice. ##
501## ------------------------------ ##
502
503AT_SETUP([%precedence does not suffice])
504
505AT_DATA([input.y],
506[[%precedence "then"
507%precedence "else"
508%%
509stmt:
510 "if" cond "then" stmt
511| "if" cond "then" stmt "else" stmt
512| "stmt"
513;
514
515cond:
516 "exp"
517| cond "then" cond
518;
519]])
520
521AT_BISON_CHECK([-o input.c input.y], 0, [],
522[[input.y: conflicts: 1 shift/reduce
523input.y:12.3-18: warning: rule useless in parser due to conflicts: cond: cond "then" cond
524]])
525
526AT_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
554AT_SETUP([Defaulted Conflicted Reduction])
555AT_KEYWORDS([report])
556
557AT_DATA([input.y],
558[[%%
559exp: num | id;
560num: '0';
561id : '0';
562%%
563]])
564
565AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
566[[input.y: conflicts: 1 reduce/reduce
567input.y:4.6-8: warning: rule useless in parser due to conflicts: id: '0'
568]])
569
570# Check the contents of the report.
571AT_CHECK([cat input.output], [],
572[[Rules useless in parser due to conflicts
573
574 4 id: '0'
575
576
577State 1 conflicts: 1 reduce/reduce
578
579
580Grammar
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
592Terminals, with rules where they appear
593
594$end (0) 0
595'0' (48) 3 4
596error (256)
597
598
599Nonterminals, with rules where they appear
600
601$accept (4)
602 on left: 0
603exp (5)
604 on left: 1 2, on right: 0
605num (6)
606 on left: 3, on right: 1
607id (7)
608 on left: 4, on right: 2
609
610
611state 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
626state 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
636state 2
637
638 0 $accept: exp . $end
639
640 $end shift, and go to state 5
641
642
643state 3
644
645 1 exp: num .
646
647 $default reduce using rule 1 (exp)
648
649
650state 4
651
652 2 exp: id .
653
654 $default reduce using rule 2 (exp)
655
656
657state 5
658
659 0 $accept: exp $end .
660
661 $default accept
662]])
663
664AT_CLEANUP
665
666
667
668
669## -------------------- ##
670## %expect not enough. ##
671## -------------------- ##
672
673AT_SETUP([%expect not enough])
674
675AT_DATA([input.y],
676[[%token NUM OP
677%expect 0
678%%
679exp: exp OP exp | NUM;
680]])
681
682AT_BISON_CHECK([-o input.c input.y], 1, [],
683[input.y: conflicts: 1 shift/reduce
684input.y: expected 0 shift/reduce conflicts
685])
686AT_CLEANUP
687
688
689## --------------- ##
690## %expect right. ##
691## --------------- ##
692
693AT_SETUP([%expect right])
694
695AT_DATA([input.y],
696[[%token NUM OP
697%expect 1
698%%
699exp: exp OP exp | NUM;
700]])
701
702AT_BISON_CHECK([-o input.c input.y])
703AT_CLEANUP
704
705
706## ------------------ ##
707## %expect too much. ##
708## ------------------ ##
709
710AT_SETUP([%expect too much])
711
712AT_DATA([input.y],
713[[%token NUM OP
714%expect 2
715%%
716exp: exp OP exp | NUM;
717]])
718
719AT_BISON_CHECK([-o input.c input.y], 1, [],
720[input.y: conflicts: 1 shift/reduce
721input.y: expected 2 shift/reduce conflicts
722])
723AT_CLEANUP
724
725
726## ------------------------------- ##
727## %expect with reduce conflicts. ##
728## ------------------------------- ##
729
730AT_SETUP([%expect with reduce conflicts])
731
732AT_DATA([input.y],
733[[%expect 0
734%%
735program: a 'a' | a a;
736a: 'a';
737]])
738
739AT_BISON_CHECK([-o input.c input.y], 1, [],
740[input.y: conflicts: 1 reduce/reduce
741input.y: expected 0 reduce/reduce conflicts
742])
743AT_CLEANUP
744
745
746## ------------------------- ##
747## %prec with user strings. ##
748## ------------------------- ##
749
750AT_SETUP([%prec with user string])
751
752AT_DATA([[input.y]],
753[[%%
754exp:
755 "foo" %prec "foo"
756;
757]])
758
759AT_BISON_CHECK([-o input.c input.y])
760AT_CLEANUP
761
762
763## -------------------------------- ##
764## %no-default-prec without %prec. ##
765## -------------------------------- ##
766
767AT_SETUP([%no-default-prec without %prec])
768
769AT_DATA([[input.y]],
770[[%left '+'
771%left '*'
772
773%%
774
775%no-default-prec;
776
777e: e '+' e
778 | e '*' e
779 | '0'
780 ;
781]])
782
783AT_BISON_CHECK([-o input.c input.y], 0, [],
784[[input.y: conflicts: 4 shift/reduce
785]])
786AT_CLEANUP
787
788
789## ----------------------------- ##
790## %no-default-prec with %prec. ##
791## ----------------------------- ##
792
793AT_SETUP([%no-default-prec with %prec])
794
795AT_DATA([[input.y]],
796[[%left '+'
797%left '*'
798
799%%
800
801%no-default-prec;
802
803e: e '+' e %prec '+'
804 | e '*' e %prec '*'
805 | '0'
806 ;
807]])
808
809AT_BISON_CHECK([-o input.c input.y])
810AT_CLEANUP
811
812
813## --------------- ##
814## %default-prec. ##
815## --------------- ##
816
817AT_SETUP([%default-prec])
818
819AT_DATA([[input.y]],
820[[%left '+'
821%left '*'
822
823%%
824
825%default-prec;
826
827e: e '+' e
828 | e '*' e
829 | '0'
830 ;
831]])
832
833AT_BISON_CHECK([-o input.c input.y])
834AT_CLEANUP
835
836
837## ---------------------------------------------- ##
838## Unreachable States After Conflict Resolution. ##
839## ---------------------------------------------- ##
840
841AT_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
848AT_DATA([[input.y]],
849[[%output "input.c"
850%left 'a'
851
852%%
853
854start: 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. */
859resolved_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. */
867unreachable1:
868 'a' unreachable2
869 |
870 ;
871
872/* Likewise for a R/R conflict and nonterminal unreachable2. */
873unreachable2: | ;
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. */
877reported_conflicts:
878 'a'
879 | 'a'
880 |
881 ;
882
883]])
884
885AT_BISON_CHECK([[--report=all input.y]], 0, [],
886[[input.y: conflicts: 1 shift/reduce, 1 reduce/reduce
887input.y:12.5-20: warning: rule useless in parser due to conflicts: resolved_conflict: 'a' unreachable1
888input.y:20.5-20: warning: rule useless in parser due to conflicts: unreachable1: 'a' unreachable2
889input.y:21.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */
890input.y:25.13: warning: rule useless in parser due to conflicts: unreachable2: /* empty */
891input.y:25.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */
892input.y:31.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a'
893input.y:32.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */
894]])
895
896AT_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
911State 4 conflicts: 1 shift/reduce
912State 5 conflicts: 1 reduce/reduce
913
914
915Grammar
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
935Terminals, with rules where they appear
936
937$end (0) 0
938'a' (97) 1 2 4 8 9
939error (256)
940
941
942Nonterminals, with rules where they appear
943
944$accept (4)
945 on left: 0
946start (5)
947 on left: 1, on right: 0
948resolved_conflict (6)
949 on left: 2 3, on right: 1
950unreachable1 (7)
951 on left: 4 5, on right: 2
952unreachable2 (8)
953 on left: 6 7, on right: 4
954reported_conflicts (9)
955 on left: 8 9 10, on right: 1
956
957
958state 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
973state 1
974
975 0 $accept: start . $end
976
977 $end shift, and go to state 3
978
979
980state 2
981
982 1 start: resolved_conflict . 'a' reported_conflicts 'a'
983
984 'a' shift, and go to state 4
985
986
987state 3
988
989 0 $accept: start $end .
990
991 $default accept
992
993
994state 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
1008state 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
1018state 6
1019
1020 1 start: resolved_conflict 'a' reported_conflicts . 'a'
1021
1022 'a' shift, and go to state 7
1023
1024
1025state 7
1026
1027 1 start: resolved_conflict 'a' reported_conflicts 'a' .
1028
1029 $default reduce using rule 1 (start)
1030]])
1031
1032AT_DATA([[input-keep.y]],
1033[[%define lr.keep-unreachable-states
1034]])
1035AT_CHECK([[cat input.y >> input-keep.y]])
1036
1037AT_BISON_CHECK([[input-keep.y]], 0, [],
1038[[input-keep.y: conflicts: 2 shift/reduce, 2 reduce/reduce
1039input-keep.y:22.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */
1040input-keep.y:26.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */
1041input-keep.y:32.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a'
1042input-keep.y:33.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */
1043]])
1044
1045AT_CLEANUP
1046
1047
1048## ------------------------------------------------------------ ##
1049## Solved conflicts report for multiple reductions in a state. ##
1050## ------------------------------------------------------------ ##
1051
1052AT_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
1056AT_DATA([[input.y]],
1057[[%left 'a'
1058%right 'b'
1059%right 'c'
1060%right 'd'
1061%%
1062start:
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 ;
1072empty_a: %prec 'a' ;
1073empty_b: %prec 'b' ;
1074empty_c1: %prec 'c' ;
1075empty_c2: %prec 'c' ;
1076empty_c3: %prec 'd' ;
1077]])
1078AT_BISON_CHECK([[--report=all -o input.c input.y]], 0, [], [ignore])
1079AT_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
1116state 1
1117]])
1118
1119AT_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
1132AT_SETUP([[%nonassoc error actions for multiple reductions in a state]])
1133
1134AT_DATA([[input.y]],
1135[[%nonassoc 'a' 'b' 'c'
1136%%
1137start:
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 ;
1147empty_a: %prec 'a' ;
1148empty_b: %prec 'b' ;
1149empty_c1: %prec 'c' ;
1150empty_c2: %prec 'c' ;
1151empty_c3: %prec 'c' ;
1152]])
1153
1154AT_BISON_CHECK([[--report=all -o input.c input.y]], 0, [], [ignore])
1155AT_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
1192state 1
1193]])
1194AT_CLEANUP