]> git.saurik.com Git - bison.git/blob - tests/conflicts.at
doc: use @group to improve page breaking
[bison.git] / tests / conflicts.at
1 # Exercising Bison on conflicts. -*- Autotest -*-
2
3 # Copyright (C) 2002-2005, 2007-2013 Free Software Foundation, Inc.
4
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 AT_BANNER([[Conflicts.]])
19
20 ## ------------------------- ##
21 ## Token declaration order. ##
22 ## ------------------------- ##
23
24 # This test checks that token are declared left to right when in a precedence
25 # statement.
26
27 AT_SETUP([Token declaration order])
28
29 AT_BISON_OPTION_PUSHDEFS
30
31 AT_DATA_GRAMMAR([[input.y]],
32 [[%code {
33 #include <stdio.h>
34 ]AT_YYERROR_DECLARE[
35 ]AT_YYLEX_DECLARE[
36 }
37 %token A B C
38 %token D
39 %right E F G
40 %right H I
41 %right J
42 %left K
43 %left L M N
44 %nonassoc O P Q
45 %precedence R S T U
46 %precedence V W
47 %%
48 exp: A
49 %%
50 ]AT_YYERROR_DEFINE[
51 ]AT_YYLEX_DEFINE[
52 int main (void)
53 {
54 assert (A < B);
55 assert (B < C);
56 assert (C < D);
57 assert (D < E);
58 assert (E < F);
59 assert (F < G);
60 assert (G < H);
61 assert (H < I);
62 assert (I < J);
63 assert (J < K);
64 assert (K < L);
65 assert (L < M);
66 assert (M < N);
67 assert (N < O);
68 assert (O < P);
69 assert (P < Q);
70 assert (Q < R);
71 assert (R < S);
72 assert (S < T);
73 assert (T < U);
74 assert (U < V);
75 assert (V < W);
76 return 0;
77 }
78 ]])
79
80 AT_BISON_CHECK([-o input.c input.y])
81 AT_COMPILE([input])
82
83 AT_PARSER_CHECK([./input])
84
85 AT_BISON_OPTION_POPDEFS
86
87 AT_CLEANUP
88
89
90 ## ------------------------------- ##
91 ## Useless associativity warning. ##
92 ## ------------------------------- ##
93
94 AT_SETUP([Useless associativity warning])
95
96 AT_DATA([[input.y]],
97 [[%nonassoc "="
98 %left "+"
99 %left "*"
100 %precedence "("
101 %%
102 stmt:
103 exp
104 | "var" "=" exp
105 ;
106
107 exp:
108 exp "+" exp
109 | exp "*" "num"
110 | "(" exp ")"
111 | "num"
112 ;
113 ]])
114
115 AT_BISON_CHECK([-Wprecedence input.y], 0, [],
116 [[input.y:1.11-13: warning: useless precedence and associativity for "=" [-Wprecedence]
117 input.y:3.7-9: warning: useless associativity for "*", use %precedence [-Wprecedence]
118 input.y:4.13-15: warning: useless precedence for "(" [-Wprecedence]
119 ]])
120
121 AT_CLEANUP
122
123
124 ## ---------------------------- ##
125 ## Useless precedence warning. ##
126 ## ---------------------------- ##
127
128 AT_SETUP([Useless precedence warning])
129
130 AT_DATA([[input.y]],
131 [[%token A B
132 %precedence Z
133 %left X
134 %precedence Y
135 %left W
136 %right V
137 %nonassoc U
138 %%
139 a: b
140 | a U b
141 | f
142 ;
143 b: c
144 | b V c
145 ;
146 c: d
147 | c W d
148 ;
149 d: A
150 | d X d
151 | d Y A
152 ;
153 f: B
154 | f Z B
155 ;
156 ]])
157
158 AT_BISON_CHECK([-Wprecedence -fcaret -o input.c input.y], 0, [],
159 [[input.y:2.13: warning: useless precedence for Z [-Wprecedence]
160 %precedence Z
161 ^
162 input.y:5.7: warning: useless precedence and associativity for W [-Wprecedence]
163 %left W
164 ^
165 input.y:6.8: warning: useless precedence and associativity for V [-Wprecedence]
166 %right V
167 ^
168 input.y:7.11: warning: useless precedence and associativity for U [-Wprecedence]
169 %nonassoc U
170 ^
171 ]])
172
173 AT_CLEANUP
174
175
176 ## ---------------- ##
177 ## S/R in initial. ##
178 ## ---------------- ##
179
180 # I once hacked Bison in such a way that it lost its reductions on the
181 # initial state (because it was confusing it with the last state). It
182 # took me a while to strip down my failures to this simple case. So
183 # make sure it finds the s/r conflict below.
184
185 AT_SETUP([S/R in initial])
186
187 AT_DATA([[input.y]],
188 [[%expect 1
189 %%
190 exp: e 'e';
191 e: 'e' | /* Nothing. */;
192 ]])
193
194 AT_BISON_CHECK([-o input.c input.y], 0, [],
195 [[input.y:4.9: warning: rule useless in parser due to conflicts: e: /* empty */ [-Wother]
196 ]])
197
198 AT_BISON_CHECK([-fcaret -o input.c input.y], 0, [],
199 [[input.y:4.9: warning: rule useless in parser due to conflicts [-Wother]
200 e: 'e' | /* Nothing. */;
201 ^
202 ]])
203
204 AT_CLEANUP
205
206
207 ## ------------------- ##
208 ## %nonassoc and eof. ##
209 ## ------------------- ##
210
211 AT_SETUP([%nonassoc and eof])
212
213 AT_BISON_OPTION_PUSHDEFS
214 AT_DATA_GRAMMAR([input.y],
215 [[
216 %{
217 #include <stdio.h>
218 #include <stdlib.h>
219 #include <string.h>
220 #include <assert.h>
221
222 #define YYERROR_VERBOSE 1
223 ]AT_YYERROR_DEFINE[
224 /* The current argument. */
225 static const char *input;
226
227 static int
228 yylex (void)
229 {
230 static size_t toknum;
231 assert (toknum <= strlen (input));
232 return input[toknum++];
233 }
234
235 %}
236
237 %nonassoc '<' '>'
238
239 %%
240 expr: expr '<' expr
241 | expr '>' expr
242 | '0'
243 ;
244 %%
245 int
246 main (int argc, const char *argv[])
247 {
248 input = argc <= 1 ? "" : argv[1];
249 return yyparse ();
250 }
251 ]])
252 AT_BISON_OPTION_POPDEFS
253
254 m4_pushdef([AT_NONASSOC_AND_EOF_CHECK],
255 [AT_BISON_CHECK([$1[ -o input.c input.y]])
256 AT_COMPILE([input])
257
258 m4_pushdef([AT_EXPECTING], [m4_if($2, [correct], [[, expecting $end]])])
259
260 AT_PARSER_CHECK([./input '0<0'])
261 AT_PARSER_CHECK([./input '0<0<0'], [1], [],
262 [syntax error, unexpected '<'AT_EXPECTING
263 ])
264
265 AT_PARSER_CHECK([./input '0>0'])
266 AT_PARSER_CHECK([./input '0>0>0'], [1], [],
267 [syntax error, unexpected '>'AT_EXPECTING
268 ])
269
270 AT_PARSER_CHECK([./input '0<0>0'], [1], [],
271 [syntax error, unexpected '>'AT_EXPECTING
272 ])
273
274 m4_popdef([AT_EXPECTING])])
275
276 # Expected token list is missing.
277 AT_NONASSOC_AND_EOF_CHECK([], [[incorrect]])
278
279 # We must disable default reductions in inconsistent states in order to
280 # have an explicit list of all expected tokens.
281 AT_NONASSOC_AND_EOF_CHECK([[-Dlr.default-reduction=consistent]],
282 [[correct]])
283
284 # lr.default-reduction=consistent happens to work for this test case.
285 # However, for other grammars, lookahead sets can be merged for
286 # different left contexts, so it is still possible to have an incorrect
287 # expected list. Canonical LR is almost a general solution (that is, it
288 # can fail only when %nonassoc is used), so make sure it gives the same
289 # result as above.
290 AT_NONASSOC_AND_EOF_CHECK([[-Dlr.type=canonical-lr]], [[correct]])
291
292 # parse.lac=full is a completely general solution that does not require
293 # any of the above sacrifices. Of course, it does not extend the
294 # language-recognition power of LALR to (IE)LR, but it does ensure that
295 # the reported list of expected tokens matches what the given parser
296 # would have accepted in place of the unexpected token.
297 AT_NONASSOC_AND_EOF_CHECK([[-Dparse.lac=full]], [[correct]])
298
299 m4_popdef([AT_NONASSOC_AND_EOF_CHECK])
300
301 AT_CLEANUP
302
303
304
305 ## ------------------------------------------- ##
306 ## parse.error=verbose and consistent errors. ##
307 ## ------------------------------------------- ##
308
309 AT_SETUP([[parse.error=verbose and consistent errors]])
310
311 m4_pushdef([AT_CONSISTENT_ERRORS_CHECK], [
312
313 AT_BISON_OPTION_PUSHDEFS([$1])
314
315 m4_pushdef([AT_YYLEX_PROTOTYPE],
316 [AT_SKEL_CC_IF([[int yylex (yy::parser::semantic_type *lvalp)]],
317 [[int yylex (YYSTYPE *lvalp)]])])
318
319 AT_SKEL_JAVA_IF([AT_DATA], [AT_DATA_GRAMMAR])([input.y],
320 [AT_SKEL_JAVA_IF([[
321
322 %code imports {
323 import java.io.IOException;
324 }]], [[
325
326 %code {]AT_SKEL_CC_IF([[
327 #include <string>]], [[
328 #include <assert.h>
329 #include <stdio.h>
330 ]AT_YYERROR_DECLARE])[
331 ]AT_YYLEX_PROTOTYPE[;
332 #define USE(Var)
333 }
334
335 ]AT_SKEL_CC_IF([[%defines]], [[%define api.pure]])])[
336
337 ]$1[
338
339 %define parse.error verbose
340
341 %%
342
343 ]$2[
344
345 ]AT_SKEL_JAVA_IF([[%code lexer {]], [[%%]])[
346
347 /*--------.
348 | yylex. |
349 `--------*/]AT_SKEL_JAVA_IF([[
350
351 public String input = "]$3[";
352 public int index = 0;
353 public int yylex ()
354 {
355 if (index < input.length ())
356 return input.charAt (index++);
357 else
358 return 0;
359 }
360 public Object getLVal ()
361 {
362 return new Integer(1);
363 }]], [[
364
365 ]AT_YYLEX_PROTOTYPE[
366 {
367 static char const *input = "]$3[";
368 *lvalp = 1;
369 return *input++;
370 }]])[
371 ]AT_YYERROR_DEFINE[
372 ]AT_SKEL_JAVA_IF([[
373 };
374
375 %%]])[
376
377 /*-------.
378 | main. |
379 `-------*/
380 ]AT_MAIN_DEFINE
381 ])
382
383 AT_FULL_COMPILE([[input]])
384
385 m4_pushdef([AT_EXPECTING], [m4_if($5, [ab], [[, expecting 'a' or 'b']],
386 $5, [a], [[, expecting 'a']],
387 $5, [b], [[, expecting 'b']])])
388
389 AT_SKEL_JAVA_IF([AT_JAVA_PARSER_CHECK([[input]], [[0]]],
390 [AT_PARSER_CHECK([[./input]], [[1]]]),
391 [[]],
392 [[syntax error, unexpected ]$4[]AT_EXPECTING[
393 ]])
394
395 m4_popdef([AT_EXPECTING])
396 m4_popdef([AT_YYLEX_PROTOTYPE])
397 AT_BISON_OPTION_POPDEFS
398
399 ])
400
401 m4_pushdef([AT_PREVIOUS_STATE_GRAMMAR],
402 [[%nonassoc 'a';
403
404 start: consistent-error-on-a-a 'a' ;
405
406 consistent-error-on-a-a:
407 'a' default-reduction
408 | 'a' default-reduction 'a'
409 | 'a' shift
410 ;
411
412 default-reduction: /*empty*/ ;
413 shift: 'b' ;
414
415 // Provide another context in which all rules are useful so that this
416 // test case looks a little more realistic.
417 start: 'b' consistent-error-on-a-a 'c' ;
418 ]])
419
420 m4_pushdef([AT_PREVIOUS_STATE_INPUT], [[a]])
421
422 # Unfortunately, no expected tokens are reported even though 'b' can be
423 # accepted. Nevertheless, the main point of this test is to make sure
424 # that at least the unexpected token is reported. In a previous version
425 # of Bison, it wasn't reported because the error is detected in a
426 # consistent state with an error action, and that case always triggered
427 # the simple "syntax error" message.
428 #
429 # The point isn't to test IELR here, but state merging happens to
430 # complicate this example.
431 AT_CONSISTENT_ERRORS_CHECK([[%define lr.type ielr]],
432 [AT_PREVIOUS_STATE_GRAMMAR],
433 [AT_PREVIOUS_STATE_INPUT],
434 [[$end]], [[none]])
435 AT_CONSISTENT_ERRORS_CHECK([[%define lr.type ielr
436 %glr-parser]],
437 [AT_PREVIOUS_STATE_GRAMMAR],
438 [AT_PREVIOUS_STATE_INPUT],
439 [[$end]], [[none]])
440 AT_CONSISTENT_ERRORS_CHECK([[%define lr.type ielr
441 %language "c++"]],
442 [AT_PREVIOUS_STATE_GRAMMAR],
443 [AT_PREVIOUS_STATE_INPUT],
444 [[$end]], [[none]])
445 AT_CONSISTENT_ERRORS_CHECK([[%define lr.type ielr
446 %language "java"]],
447 [AT_PREVIOUS_STATE_GRAMMAR],
448 [AT_PREVIOUS_STATE_INPUT],
449 [[end of input]], [[none]])
450
451 # Even canonical LR doesn't foresee the error for 'a'!
452 AT_CONSISTENT_ERRORS_CHECK([[%define lr.type ielr
453 %define lr.default-reduction consistent]],
454 [AT_PREVIOUS_STATE_GRAMMAR],
455 [AT_PREVIOUS_STATE_INPUT],
456 [[$end]], [[ab]])
457 AT_CONSISTENT_ERRORS_CHECK([[%define lr.type ielr
458 %define lr.default-reduction accepting]],
459 [AT_PREVIOUS_STATE_GRAMMAR],
460 [AT_PREVIOUS_STATE_INPUT],
461 [[$end]], [[ab]])
462 AT_CONSISTENT_ERRORS_CHECK([[%define lr.type canonical-lr]],
463 [AT_PREVIOUS_STATE_GRAMMAR],
464 [AT_PREVIOUS_STATE_INPUT],
465 [[$end]], [[ab]])
466
467 # Only LAC gets it right.
468 AT_CONSISTENT_ERRORS_CHECK([[%define lr.type canonical-lr
469 %define parse.lac full]],
470 [AT_PREVIOUS_STATE_GRAMMAR],
471 [AT_PREVIOUS_STATE_INPUT],
472 [[$end]], [[b]])
473 AT_CONSISTENT_ERRORS_CHECK([[%define lr.type ielr
474 %define parse.lac full]],
475 [AT_PREVIOUS_STATE_GRAMMAR],
476 [AT_PREVIOUS_STATE_INPUT],
477 [[$end]], [[b]])
478
479 m4_popdef([AT_PREVIOUS_STATE_GRAMMAR])
480 m4_popdef([AT_PREVIOUS_STATE_INPUT])
481
482 m4_pushdef([AT_USER_ACTION_GRAMMAR],
483 [[%nonassoc 'a';
484
485 // If $$ = 0 here, then we know that the 'a' destructor is being invoked
486 // incorrectly for the 'b' set in the semantic action below. All 'a'
487 // tokens are returned by yylex, which sets $$ = 1.
488 %destructor {
489 if (!$$)
490 fprintf (stderr, "Wrong destructor.\n");
491 } 'a';
492
493 // Rather than depend on an inconsistent state to induce reading a
494 // lookahead as in the previous grammar, just assign the lookahead in a
495 // semantic action. That lookahead isn't needed before either error
496 // action is encountered. In a previous version of Bison, this was a
497 // problem as it meant yychar was not translated into yytoken before
498 // either error action. The second error action thus invoked a
499 // destructor that it selected according to the incorrect yytoken. The
500 // first error action would have reported an incorrect unexpected token
501 // except that, due to the bug described in the previous grammar, the
502 // unexpected token was not reported at all.
503 start: error-reduce consistent-error 'a' { USE ($][3); } ;
504
505 error-reduce:
506 'a' 'a' consistent-reduction consistent-error 'a'
507 { USE (($][1, $][2, $][5)); }
508 | 'a' error
509 { USE ($][1); }
510 ;
511
512 consistent-reduction: /*empty*/ {
513 assert (yychar == YYEMPTY);
514 yylval = 0;
515 yychar = 'b';
516 } ;
517
518 consistent-error:
519 'a' { USE ($][1); }
520 | /*empty*/ %prec 'a'
521 ;
522
523 // Provide another context in which all rules are useful so that this
524 // test case looks a little more realistic.
525 start: 'b' consistent-error 'b' ;
526 ]])
527 m4_pushdef([AT_USER_ACTION_INPUT], [[aa]])
528
529 AT_CONSISTENT_ERRORS_CHECK([[]],
530 [AT_USER_ACTION_GRAMMAR],
531 [AT_USER_ACTION_INPUT],
532 [['b']], [[none]])
533 AT_CONSISTENT_ERRORS_CHECK([[%glr-parser]],
534 [AT_USER_ACTION_GRAMMAR],
535 [AT_USER_ACTION_INPUT],
536 [['b']], [[none]])
537 # No C++ or Java test because yychar cannot be manipulated by users.
538
539 AT_CONSISTENT_ERRORS_CHECK([[%define lr.default-reduction consistent]],
540 [AT_USER_ACTION_GRAMMAR],
541 [AT_USER_ACTION_INPUT],
542 [['b']], [[none]])
543
544 # Canonical LR doesn't foresee the error for 'a'!
545 AT_CONSISTENT_ERRORS_CHECK([[%define lr.default-reduction accepting]],
546 [AT_USER_ACTION_GRAMMAR],
547 [AT_USER_ACTION_INPUT],
548 [[$end]], [[a]])
549 AT_CONSISTENT_ERRORS_CHECK([[%define lr.type canonical-lr]],
550 [AT_USER_ACTION_GRAMMAR],
551 [AT_USER_ACTION_INPUT],
552 [[$end]], [[a]])
553
554 AT_CONSISTENT_ERRORS_CHECK([[%define parse.lac full]],
555 [AT_USER_ACTION_GRAMMAR],
556 [AT_USER_ACTION_INPUT],
557 [['b']], [[none]])
558 AT_CONSISTENT_ERRORS_CHECK([[%define parse.lac full
559 %define lr.default-reduction accepting]],
560 [AT_USER_ACTION_GRAMMAR],
561 [AT_USER_ACTION_INPUT],
562 [[$end]], [[none]])
563
564 m4_popdef([AT_USER_ACTION_GRAMMAR])
565 m4_popdef([AT_USER_ACTION_INPUT])
566
567 m4_popdef([AT_CONSISTENT_ERRORS_CHECK])
568
569 AT_CLEANUP
570
571
572
573 ## ------------------------------------------------------- ##
574 ## LAC: %nonassoc requires splitting canonical LR states. ##
575 ## ------------------------------------------------------- ##
576
577 # This test case demonstrates that, when %nonassoc is used, canonical
578 # LR(1) parser table construction followed by conflict resolution
579 # without further state splitting is not always sufficient to produce a
580 # parser that can detect all syntax errors as soon as possible on one
581 # token of lookahead. However, LAC solves the problem completely even
582 # with minimal LR parser tables.
583
584 AT_SETUP([[LAC: %nonassoc requires splitting canonical LR states]])
585 AT_BISON_OPTION_PUSHDEFS
586 AT_DATA_GRAMMAR([[input.y]],
587 [[%code {
588 #include <stdio.h>
589 ]AT_YYERROR_DECLARE[
590 ]AT_YYLEX_DECLARE[
591 }
592
593 %error-verbose
594 %nonassoc 'a'
595
596 %%
597
598 start:
599 'a' problem 'a' // First context.
600 | 'b' problem 'b' // Second context.
601 | 'c' reduce-nonassoc // Just makes reduce-nonassoc useful.
602 ;
603
604 problem:
605 look reduce-nonassoc
606 | look 'a'
607 | look 'b'
608 ;
609
610 // For the state reached after shifting the 'a' in these productions,
611 // lookahead sets are the same in both the first and second contexts.
612 // Thus, canonical LR reuses the same state for both contexts. However,
613 // the lookahead 'a' for the reduction "look: 'a'" later becomes an
614 // error action only in the first context. In order to immediately
615 // detect the syntax error on 'a' here for only the first context, this
616 // canonical LR state would have to be split into two states, and the
617 // 'a' lookahead would have to be removed from only one of the states.
618 look:
619 'a' // Reduction lookahead set is always ['a', 'b'].
620 | 'a' 'b'
621 | 'a' 'c' // 'c' is forgotten as an expected token.
622 ;
623
624 reduce-nonassoc: %prec 'a';
625
626 %%
627 ]AT_YYERROR_DEFINE[
628 ]AT_YYLEX_DEFINE(["aaa"])[
629 ]AT_MAIN_DEFINE
630 ])
631 AT_BISON_OPTION_POPDEFS
632
633 # Show canonical LR's failure.
634 AT_BISON_CHECK([[-Dlr.type=canonical-lr -o input.c input.y]],
635 [[0]], [[]],
636 [[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
637 ]])
638 AT_COMPILE([[input]])
639 AT_PARSER_CHECK([[./input]], [[1]], [[]],
640 [[syntax error, unexpected 'a', expecting 'b'
641 ]])
642
643 # It's corrected by LAC.
644 AT_BISON_CHECK([[-Dlr.type=canonical-lr -Dparse.lac=full \
645 -o input.c input.y]], [[0]], [[]],
646 [[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
647 ]])
648 AT_COMPILE([[input]])
649 AT_PARSER_CHECK([[./input]], [[1]], [[]],
650 [[syntax error, unexpected 'a', expecting 'b' or 'c'
651 ]])
652
653 # IELR is sufficient when LAC is used.
654 AT_BISON_CHECK([[-Dlr.type=ielr -Dparse.lac=full -o input.c input.y]],
655 [[0]], [[]],
656 [[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
657 ]])
658 AT_COMPILE([[input]])
659 AT_PARSER_CHECK([[./input]], [[1]], [[]],
660 [[syntax error, unexpected 'a', expecting 'b' or 'c'
661 ]])
662
663 AT_CLEANUP
664
665 ## ------------------------- ##
666 ## Unresolved SR Conflicts. ##
667 ## ------------------------- ##
668
669 AT_SETUP([Unresolved SR Conflicts])
670
671 AT_KEYWORDS([report])
672
673 AT_DATA([input.y],
674 [[%token NUM OP
675 %%
676 exp: exp OP exp | NUM;
677 ]])
678
679 AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
680 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
681 ]])
682
683 # Check the contents of the report.
684 AT_CHECK([cat input.output], [],
685 [[State 5 conflicts: 1 shift/reduce
686
687
688 Grammar
689
690 0 $accept: exp $end
691
692 1 exp: exp OP exp
693 2 | NUM
694
695
696 Terminals, with rules where they appear
697
698 $end (0) 0
699 error (256)
700 NUM (258) 2
701 OP (259) 1
702
703
704 Nonterminals, with rules where they appear
705
706 $accept (5)
707 on left: 0
708 exp (6)
709 on left: 1 2, on right: 0 1
710
711
712 State 0
713
714 0 $accept: . exp $end
715 1 exp: . exp OP exp
716 2 | . NUM
717
718 NUM shift, and go to state 1
719
720 exp go to state 2
721
722
723 State 1
724
725 2 exp: NUM .
726
727 $default reduce using rule 2 (exp)
728
729
730 State 2
731
732 0 $accept: exp . $end
733 1 exp: exp . OP exp
734
735 $end shift, and go to state 3
736 OP shift, and go to state 4
737
738
739 State 3
740
741 0 $accept: exp $end .
742
743 $default accept
744
745
746 State 4
747
748 1 exp: . exp OP exp
749 1 | exp OP . exp
750 2 | . NUM
751
752 NUM shift, and go to state 1
753
754 exp go to state 5
755
756
757 State 5
758
759 1 exp: exp . OP exp
760 1 | exp OP exp . [$end, OP]
761
762 OP shift, and go to state 4
763
764 OP [reduce using rule 1 (exp)]
765 $default reduce using rule 1 (exp)
766 ]])
767
768 AT_CLEANUP
769
770
771
772 ## ----------------------- ##
773 ## Resolved SR Conflicts. ##
774 ## ----------------------- ##
775
776 AT_SETUP([Resolved SR Conflicts])
777
778 AT_KEYWORDS([report])
779
780 AT_DATA([input.y],
781 [[%token NUM OP
782 %left OP
783 %%
784 exp: exp OP exp | NUM;
785 ]])
786
787 AT_BISON_CHECK([-o input.c --report=all input.y])
788
789 # Check the contents of the report.
790 AT_CHECK([cat input.output], [],
791 [[Grammar
792
793 0 $accept: exp $end
794
795 1 exp: exp OP exp
796 2 | NUM
797
798
799 Terminals, with rules where they appear
800
801 $end (0) 0
802 error (256)
803 NUM (258) 2
804 OP (259) 1
805
806
807 Nonterminals, with rules where they appear
808
809 $accept (5)
810 on left: 0
811 exp (6)
812 on left: 1 2, on right: 0 1
813
814
815 State 0
816
817 0 $accept: . exp $end
818 1 exp: . exp OP exp
819 2 | . NUM
820
821 NUM shift, and go to state 1
822
823 exp go to state 2
824
825
826 State 1
827
828 2 exp: NUM .
829
830 $default reduce using rule 2 (exp)
831
832
833 State 2
834
835 0 $accept: exp . $end
836 1 exp: exp . OP exp
837
838 $end shift, and go to state 3
839 OP shift, and go to state 4
840
841
842 State 3
843
844 0 $accept: exp $end .
845
846 $default accept
847
848
849 State 4
850
851 1 exp: . exp OP exp
852 1 | exp OP . exp
853 2 | . NUM
854
855 NUM shift, and go to state 1
856
857 exp go to state 5
858
859
860 State 5
861
862 1 exp: exp . OP exp
863 1 | exp OP exp . [$end, OP]
864
865 $default reduce using rule 1 (exp)
866
867 Conflict between rule 1 and token OP resolved as reduce (%left OP).
868 ]])
869
870 AT_CLEANUP
871
872
873 ## ---------------------- ##
874 ## %precedence suffices. ##
875 ## ---------------------- ##
876
877 AT_SETUP([%precedence suffices])
878
879 AT_DATA([input.y],
880 [[%precedence "then"
881 %precedence "else"
882 %%
883 stmt:
884 "if" cond "then" stmt
885 | "if" cond "then" stmt "else" stmt
886 | "stmt"
887 ;
888
889 cond:
890 "exp"
891 ;
892 ]])
893
894 AT_BISON_CHECK([-o input.c input.y])
895
896 AT_CLEANUP
897
898
899 ## ------------------------------ ##
900 ## %precedence does not suffice. ##
901 ## ------------------------------ ##
902
903 AT_SETUP([%precedence does not suffice])
904
905 AT_DATA([input.y],
906 [[%precedence "then"
907 %precedence "else"
908 %%
909 stmt:
910 "if" cond "then" stmt
911 | "if" cond "then" stmt "else" stmt
912 | "stmt"
913 ;
914
915 cond:
916 "exp"
917 | cond "then" cond
918 ;
919 ]])
920
921 AT_BISON_CHECK([-o input.c input.y], 0, [],
922 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
923 input.y:12.3-18: warning: rule useless in parser due to conflicts: cond: cond "then" cond [-Wother]
924 ]])
925
926 AT_CLEANUP
927
928
929 ## -------------------------------- ##
930 ## Defaulted Conflicted Reduction. ##
931 ## -------------------------------- ##
932
933 # When there are RR conflicts, some rules are disabled. Usually it is
934 # simply displayed as:
935 #
936 # $end reduce using rule 3 (num)
937 # $end [reduce using rule 4 (id)]
938 #
939 # But when `reduce 3' is the default action, we'd produce:
940 #
941 # $end [reduce using rule 4 (id)]
942 # $default reduce using rule 3 (num)
943 #
944 # In this precise case (a reduction is masked by the default
945 # reduction), we make the `reduce 3' explicit:
946 #
947 # $end reduce using rule 3 (num)
948 # $end [reduce using rule 4 (id)]
949 # $default reduce using rule 3 (num)
950 #
951 # Maybe that's not the best display, but then, please propose something
952 # else.
953
954 AT_SETUP([Defaulted Conflicted Reduction])
955 AT_KEYWORDS([report])
956
957 AT_DATA([input.y],
958 [[%%
959 exp: num | id;
960 num: '0';
961 id : '0';
962 %%
963 ]])
964
965 AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
966 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
967 input.y:4.6-8: warning: rule useless in parser due to conflicts: id: '0' [-Wother]
968 ]])
969
970 # Check the contents of the report.
971 AT_CHECK([cat input.output], [],
972 [[Rules useless in parser due to conflicts
973
974 4 id: '0'
975
976
977 State 1 conflicts: 1 reduce/reduce
978
979
980 Grammar
981
982 0 $accept: exp $end
983
984 1 exp: num
985 2 | id
986
987 3 num: '0'
988
989 4 id: '0'
990
991
992 Terminals, with rules where they appear
993
994 $end (0) 0
995 '0' (48) 3 4
996 error (256)
997
998
999 Nonterminals, with rules where they appear
1000
1001 $accept (4)
1002 on left: 0
1003 exp (5)
1004 on left: 1 2, on right: 0
1005 num (6)
1006 on left: 3, on right: 1
1007 id (7)
1008 on left: 4, on right: 2
1009
1010
1011 State 0
1012
1013 0 $accept: . exp $end
1014 1 exp: . num
1015 2 | . id
1016 3 num: . '0'
1017 4 id: . '0'
1018
1019 '0' shift, and go to state 1
1020
1021 exp go to state 2
1022 num go to state 3
1023 id go to state 4
1024
1025
1026 State 1
1027
1028 3 num: '0' . [$end]
1029 4 id: '0' . [$end]
1030
1031 $end reduce using rule 3 (num)
1032 $end [reduce using rule 4 (id)]
1033 $default reduce using rule 3 (num)
1034
1035
1036 State 2
1037
1038 0 $accept: exp . $end
1039
1040 $end shift, and go to state 5
1041
1042
1043 State 3
1044
1045 1 exp: num .
1046
1047 $default reduce using rule 1 (exp)
1048
1049
1050 State 4
1051
1052 2 exp: id .
1053
1054 $default reduce using rule 2 (exp)
1055
1056
1057 State 5
1058
1059 0 $accept: exp $end .
1060
1061 $default accept
1062 ]])
1063
1064 AT_CLEANUP
1065
1066
1067
1068
1069 ## -------------------- ##
1070 ## %expect not enough. ##
1071 ## -------------------- ##
1072
1073 AT_SETUP([%expect not enough])
1074
1075 AT_DATA([input.y],
1076 [[%token NUM OP
1077 %expect 0
1078 %%
1079 exp: exp OP exp | NUM;
1080 ]])
1081
1082 AT_BISON_CHECK([-o input.c input.y], 1, [],
1083 [[input.y: error: shift/reduce conflicts: 1 found, 0 expected
1084 ]])
1085 AT_CLEANUP
1086
1087
1088 ## --------------- ##
1089 ## %expect right. ##
1090 ## --------------- ##
1091
1092 AT_SETUP([%expect right])
1093
1094 AT_DATA([input.y],
1095 [[%token NUM OP
1096 %expect 1
1097 %%
1098 exp: exp OP exp | NUM;
1099 ]])
1100
1101 AT_BISON_CHECK([-o input.c input.y])
1102 AT_CLEANUP
1103
1104
1105 ## ------------------ ##
1106 ## %expect too much. ##
1107 ## ------------------ ##
1108
1109 AT_SETUP([%expect too much])
1110
1111 AT_DATA([input.y],
1112 [[%token NUM OP
1113 %expect 2
1114 %%
1115 exp: exp OP exp | NUM;
1116 ]])
1117
1118 AT_BISON_CHECK([-o input.c input.y], 1, [],
1119 [[input.y: error: shift/reduce conflicts: 1 found, 2 expected
1120 ]])
1121 AT_CLEANUP
1122
1123
1124 ## ------------------------------- ##
1125 ## %expect with reduce conflicts. ##
1126 ## ------------------------------- ##
1127
1128 AT_SETUP([%expect with reduce conflicts])
1129
1130 AT_DATA([input.y],
1131 [[%expect 0
1132 %%
1133 program: a 'a' | a a;
1134 a: 'a';
1135 ]])
1136
1137 AT_BISON_CHECK([-o input.c input.y], 1, [],
1138 [[input.y: error: reduce/reduce conflicts: 1 found, 0 expected
1139 ]])
1140 AT_CLEANUP
1141
1142
1143 ## ------------------------- ##
1144 ## %prec with user strings. ##
1145 ## ------------------------- ##
1146
1147 AT_SETUP([%prec with user string])
1148
1149 AT_DATA([[input.y]],
1150 [[%%
1151 exp:
1152 "foo" %prec "foo"
1153 ;
1154 ]])
1155
1156 AT_BISON_CHECK([-o input.c input.y])
1157 AT_CLEANUP
1158
1159
1160 ## -------------------------------- ##
1161 ## %no-default-prec without %prec. ##
1162 ## -------------------------------- ##
1163
1164 AT_SETUP([%no-default-prec without %prec])
1165
1166 AT_DATA([[input.y]],
1167 [[%left '+'
1168 %left '*'
1169
1170 %%
1171
1172 %no-default-prec;
1173
1174 e: e '+' e
1175 | e '*' e
1176 | '0'
1177 ;
1178 ]])
1179
1180 AT_BISON_CHECK([-Wall -o input.c input.y], 0, [],
1181 [[input.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr]
1182 input.y:1.7-9: warning: useless precedence and associativity for '+' [-Wprecedence]
1183 input.y:2.7-9: warning: useless precedence and associativity for '*' [-Wprecedence]
1184 ]])
1185 AT_CLEANUP
1186
1187
1188 ## ----------------------------- ##
1189 ## %no-default-prec with %prec. ##
1190 ## ----------------------------- ##
1191
1192 AT_SETUP([%no-default-prec with %prec])
1193
1194 AT_DATA([[input.y]],
1195 [[%left '+'
1196 %left '*'
1197
1198 %%
1199
1200 %no-default-prec;
1201
1202 e: e '+' e %prec '+'
1203 | e '*' e %prec '*'
1204 | '0'
1205 ;
1206 ]])
1207
1208 AT_BISON_CHECK([-o input.c input.y])
1209 AT_CLEANUP
1210
1211
1212 ## --------------- ##
1213 ## %default-prec. ##
1214 ## --------------- ##
1215
1216 AT_SETUP([%default-prec])
1217
1218 AT_DATA([[input.y]],
1219 [[%left '+'
1220 %left '*'
1221
1222 %%
1223
1224 %default-prec;
1225
1226 e: e '+' e
1227 | e '*' e
1228 | '0'
1229 ;
1230 ]])
1231
1232 AT_BISON_CHECK([-o input.c input.y])
1233 AT_CLEANUP
1234
1235
1236 ## ---------------------------------------------- ##
1237 ## Unreachable States After Conflict Resolution. ##
1238 ## ---------------------------------------------- ##
1239
1240 AT_SETUP([[Unreachable States After Conflict Resolution]])
1241
1242 # If conflict resolution makes states unreachable, remove those states, report
1243 # rules that are then unused, and don't report conflicts in those states. Test
1244 # what happens when a nonterminal becomes useless as a result of state removal
1245 # since that causes lalr.o's goto map to be rewritten.
1246
1247 AT_DATA([[input.y]],
1248 [[%output "input.c"
1249 %left 'a'
1250
1251 %%
1252
1253 start: resolved_conflict 'a' reported_conflicts 'a' ;
1254
1255 /* S/R conflict resolved as reduce, so the state with item
1256 * (resolved_conflict: 'a' . unreachable1) and all it transition successors are
1257 * unreachable, and the associated production is useless. */
1258 resolved_conflict:
1259 'a' unreachable1
1260 | %prec 'a'
1261 ;
1262
1263 /* S/R conflict that need not be reported since it is unreachable because of
1264 * the previous conflict resolution. Nonterminal unreachable1 and all its
1265 * productions are useless. */
1266 unreachable1:
1267 'a' unreachable2
1268 |
1269 ;
1270
1271 /* Likewise for a R/R conflict and nonterminal unreachable2. */
1272 unreachable2: | ;
1273
1274 /* Make sure remaining S/R and R/R conflicts are still reported correctly even
1275 * when their states are renumbered due to state removal. */
1276 reported_conflicts:
1277 'a'
1278 | 'a'
1279 |
1280 ;
1281
1282 ]])
1283
1284 AT_BISON_CHECK([[--report=all input.y]], 0, [],
1285 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
1286 input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1287 input.y:12.5-20: warning: rule useless in parser due to conflicts: resolved_conflict: 'a' unreachable1 [-Wother]
1288 input.y:20.5-20: warning: rule useless in parser due to conflicts: unreachable1: 'a' unreachable2 [-Wother]
1289 input.y:21.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */ [-Wother]
1290 input.y:25.13: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother]
1291 input.y:25.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother]
1292 input.y:31.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a' [-Wother]
1293 input.y:32.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ [-Wother]
1294 ]])
1295
1296 AT_CHECK([[cat input.output]], 0,
1297 [[Rules useless in parser due to conflicts
1298
1299 2 resolved_conflict: 'a' unreachable1
1300
1301 4 unreachable1: 'a' unreachable2
1302 5 | /* empty */
1303
1304 6 unreachable2: /* empty */
1305 7 | /* empty */
1306
1307 9 reported_conflicts: 'a'
1308 10 | /* empty */
1309
1310
1311 State 4 conflicts: 1 shift/reduce
1312 State 5 conflicts: 1 reduce/reduce
1313
1314
1315 Grammar
1316
1317 0 $accept: start $end
1318
1319 1 start: resolved_conflict 'a' reported_conflicts 'a'
1320
1321 2 resolved_conflict: 'a' unreachable1
1322 3 | /* empty */
1323
1324 4 unreachable1: 'a' unreachable2
1325 5 | /* empty */
1326
1327 6 unreachable2: /* empty */
1328 7 | /* empty */
1329
1330 8 reported_conflicts: 'a'
1331 9 | 'a'
1332 10 | /* empty */
1333
1334
1335 Terminals, with rules where they appear
1336
1337 $end (0) 0
1338 'a' (97) 1 2 4 8 9
1339 error (256)
1340
1341
1342 Nonterminals, with rules where they appear
1343
1344 $accept (4)
1345 on left: 0
1346 start (5)
1347 on left: 1, on right: 0
1348 resolved_conflict (6)
1349 on left: 2 3, on right: 1
1350 unreachable1 (7)
1351 on left: 4 5, on right: 2
1352 unreachable2 (8)
1353 on left: 6 7, on right: 4
1354 reported_conflicts (9)
1355 on left: 8 9 10, on right: 1
1356
1357
1358 State 0
1359
1360 0 $accept: . start $end
1361 1 start: . resolved_conflict 'a' reported_conflicts 'a'
1362 2 resolved_conflict: . 'a' unreachable1
1363 3 | . ['a']
1364
1365 $default reduce using rule 3 (resolved_conflict)
1366
1367 start go to state 1
1368 resolved_conflict go to state 2
1369
1370 Conflict between rule 3 and token 'a' resolved as reduce (%left 'a').
1371
1372
1373 State 1
1374
1375 0 $accept: start . $end
1376
1377 $end shift, and go to state 3
1378
1379
1380 State 2
1381
1382 1 start: resolved_conflict . 'a' reported_conflicts 'a'
1383
1384 'a' shift, and go to state 4
1385
1386
1387 State 3
1388
1389 0 $accept: start $end .
1390
1391 $default accept
1392
1393
1394 State 4
1395
1396 1 start: resolved_conflict 'a' . reported_conflicts 'a'
1397 8 reported_conflicts: . 'a'
1398 9 | . 'a'
1399 10 | . ['a']
1400
1401 'a' shift, and go to state 5
1402
1403 'a' [reduce using rule 10 (reported_conflicts)]
1404
1405 reported_conflicts go to state 6
1406
1407
1408 State 5
1409
1410 8 reported_conflicts: 'a' . ['a']
1411 9 | 'a' . ['a']
1412
1413 'a' reduce using rule 8 (reported_conflicts)
1414 'a' [reduce using rule 9 (reported_conflicts)]
1415 $default reduce using rule 8 (reported_conflicts)
1416
1417
1418 State 6
1419
1420 1 start: resolved_conflict 'a' reported_conflicts . 'a'
1421
1422 'a' shift, and go to state 7
1423
1424
1425 State 7
1426
1427 1 start: resolved_conflict 'a' reported_conflicts 'a' .
1428
1429 $default reduce using rule 1 (start)
1430 ]])
1431
1432 AT_DATA([[input-keep.y]],
1433 [[%define lr.keep-unreachable-state
1434 ]])
1435 AT_CHECK([[cat input.y >> input-keep.y]])
1436
1437 AT_BISON_CHECK([[input-keep.y]], 0, [],
1438 [[input-keep.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
1439 input-keep.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
1440 input-keep.y:22.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */ [-Wother]
1441 input-keep.y:26.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother]
1442 input-keep.y:32.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a' [-Wother]
1443 input-keep.y:33.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ [-Wother]
1444 ]])
1445
1446 AT_CLEANUP
1447
1448
1449 ## ------------------------------------------------------------ ##
1450 ## Solved conflicts report for multiple reductions in a state. ##
1451 ## ------------------------------------------------------------ ##
1452
1453 AT_SETUP([[Solved conflicts report for multiple reductions in a state]])
1454
1455 # Used to lose earlier solved conflict messages even within a single S/R/R.
1456
1457 AT_DATA([[input.y]],
1458 [[%left 'a'
1459 %right 'b'
1460 %right 'c'
1461 %right 'd'
1462 %%
1463 start:
1464 'a'
1465 | empty_a 'a'
1466 | 'b'
1467 | empty_b 'b'
1468 | 'c'
1469 | empty_c1 'c'
1470 | empty_c2 'c'
1471 | empty_c3 'c'
1472 ;
1473 empty_a: %prec 'a' ;
1474 empty_b: %prec 'b' ;
1475 empty_c1: %prec 'c' ;
1476 empty_c2: %prec 'c' ;
1477 empty_c3: %prec 'd' ;
1478 ]])
1479 AT_BISON_CHECK([[--report=all -o input.c input.y]], 0, [], [ignore])
1480 AT_CHECK([[cat input.output | sed -n '/^State 0$/,/^State 1$/p']], 0,
1481 [[State 0
1482
1483 0 $accept: . start $end
1484 1 start: . 'a'
1485 2 | . empty_a 'a'
1486 3 | . 'b'
1487 4 | . empty_b 'b'
1488 5 | . 'c'
1489 6 | . empty_c1 'c'
1490 7 | . empty_c2 'c'
1491 8 | . empty_c3 'c'
1492 9 empty_a: . ['a']
1493 10 empty_b: . []
1494 11 empty_c1: . []
1495 12 empty_c2: . []
1496 13 empty_c3: . ['c']
1497
1498 'b' shift, and go to state 1
1499
1500 'c' reduce using rule 13 (empty_c3)
1501 $default reduce using rule 9 (empty_a)
1502
1503 start go to state 2
1504 empty_a go to state 3
1505 empty_b go to state 4
1506 empty_c1 go to state 5
1507 empty_c2 go to state 6
1508 empty_c3 go to state 7
1509
1510 Conflict between rule 9 and token 'a' resolved as reduce (%left 'a').
1511 Conflict between rule 10 and token 'b' resolved as shift (%right 'b').
1512 Conflict between rule 11 and token 'c' resolved as shift (%right 'c').
1513 Conflict between rule 12 and token 'c' resolved as shift (%right 'c').
1514 Conflict between rule 13 and token 'c' resolved as reduce ('c' < 'd').
1515
1516
1517 State 1
1518 ]])
1519
1520 AT_CLEANUP
1521
1522
1523 ## ------------------------------------------------------------ ##
1524 ## %nonassoc error actions for multiple reductions in a state. ##
1525 ## ------------------------------------------------------------ ##
1526
1527 # Used to abort when trying to resolve conflicts as %nonassoc error actions for
1528 # multiple reductions in a state.
1529
1530 # For a %nonassoc error action token, used to print the first remaining
1531 # reduction on that token without brackets.
1532
1533 AT_SETUP([[%nonassoc error actions for multiple reductions in a state]])
1534
1535 AT_DATA([[input.y]],
1536 [[%nonassoc 'a' 'b' 'c'
1537 %%
1538 start:
1539 'a'
1540 | empty_a 'a'
1541 | 'b'
1542 | empty_b 'b'
1543 | 'c'
1544 | empty_c1 'c'
1545 | empty_c2 'c'
1546 | empty_c3 'c'
1547 ;
1548 empty_a: %prec 'a' ;
1549 empty_b: %prec 'b' ;
1550 empty_c1: %prec 'c' ;
1551 empty_c2: %prec 'c' ;
1552 empty_c3: %prec 'c' ;
1553 ]])
1554
1555 AT_BISON_CHECK([[--report=all -o input.c input.y]], 0, [], [ignore])
1556 AT_CHECK([[cat input.output | sed -n '/^State 0$/,/^State 1$/p']], 0,
1557 [[State 0
1558
1559 0 $accept: . start $end
1560 1 start: . 'a'
1561 2 | . empty_a 'a'
1562 3 | . 'b'
1563 4 | . empty_b 'b'
1564 5 | . 'c'
1565 6 | . empty_c1 'c'
1566 7 | . empty_c2 'c'
1567 8 | . empty_c3 'c'
1568 9 empty_a: . []
1569 10 empty_b: . []
1570 11 empty_c1: . []
1571 12 empty_c2: . ['c']
1572 13 empty_c3: . ['c']
1573
1574 'a' error (nonassociative)
1575 'b' error (nonassociative)
1576 'c' error (nonassociative)
1577
1578 'c' [reduce using rule 12 (empty_c2)]
1579 'c' [reduce using rule 13 (empty_c3)]
1580
1581 start go to state 1
1582 empty_a go to state 2
1583 empty_b go to state 3
1584 empty_c1 go to state 4
1585 empty_c2 go to state 5
1586 empty_c3 go to state 6
1587
1588 Conflict between rule 9 and token 'a' resolved as an error (%nonassoc 'a').
1589 Conflict between rule 10 and token 'b' resolved as an error (%nonassoc 'b').
1590 Conflict between rule 11 and token 'c' resolved as an error (%nonassoc 'c').
1591
1592
1593 State 1
1594 ]])
1595 AT_CLEANUP
1596
1597
1598 ## -------------------- ##
1599 ## %expect-rr non GLR. ##
1600 ## -------------------- ##
1601
1602 AT_SETUP([[%expect-rr non GLR]])
1603
1604 AT_DATA([[1.y]],
1605 [[%expect-rr 0
1606 %%
1607 exp: 'a'
1608 ]])
1609
1610 AT_BISON_CHECK([[1.y]], [[0]], [],
1611 [[1.y: warning: %expect-rr applies only to GLR parsers [-Wother]
1612 ]])
1613
1614 AT_DATA([[2.y]],
1615 [[%expect-rr 1
1616 %%
1617 exp: 'a' | 'a';
1618 ]])
1619
1620 AT_BISON_CHECK([[2.y]], [[0]], [],
1621 [[2.y: warning: %expect-rr applies only to GLR parsers [-Wother]
1622 2.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1623 2.y:3.12-14: warning: rule useless in parser due to conflicts: exp: 'a' [-Wother]
1624 ]])
1625
1626 AT_CLEANUP
1627
1628
1629 ## ---------------------------------- ##
1630 ## -W versus %expect and %expect-rr. ##
1631 ## ---------------------------------- ##
1632
1633 AT_SETUP([[-W versus %expect and %expect-rr]])
1634
1635 AT_DATA([[sr-rr.y]],
1636 [[%glr-parser
1637 %%
1638 start: 'a' | A 'a' | B 'a' ;
1639 A: ;
1640 B: ;
1641 ]])
1642 AT_DATA([[sr.y]],
1643 [[%glr-parser
1644 %%
1645 start: 'a' | A 'a' ;
1646 A: ;
1647 ]])
1648 AT_DATA([[rr.y]],
1649 [[%glr-parser
1650 %%
1651 start: A | B ;
1652 A: ;
1653 B: ;
1654 ]])
1655
1656 AT_BISON_CHECK([[sr-rr.y]], [[0]], [[]],
1657 [[sr-rr.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
1658 sr-rr.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1659 ]])
1660 AT_BISON_CHECK([[-Wno-conflicts-sr sr-rr.y]], [[0]], [[]],
1661 [[sr-rr.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1662 ]])
1663 AT_BISON_CHECK([[-Wno-conflicts-rr sr-rr.y]], [[0]], [[]],
1664 [[sr-rr.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
1665 ]])
1666
1667 [
1668 # This is piece of code is rather complex for a simple task: try every
1669 # combinaison of (0 or 1 real SR) x (0 or 1 real RR) x (don't %expect
1670 # or %expect 0, 1, or 2 SR) x (don't %expect-rr or %expect-rr 0, 1, or 2
1671 # RR).
1672
1673 # Number and types of genuine conflicts in the grammar.
1674 for gram in sr-rr sr rr; do
1675 # Number of expected s/r conflicts.
1676 for sr_exp_i in '' 0 1 2; do
1677 # Number of expected r/r conflicts.
1678 for rr_exp_i in '' 0 1 2; do
1679 test -z "$sr_exp_i" && test -z "$rr_exp_i" && continue
1680
1681 # Build grammar file.
1682 sr_exp=0
1683 rr_exp=0
1684 file=$gram
1685 directives=
1686 if test -n "$sr_exp_i"; then
1687 sr_exp=$sr_exp_i
1688 file=$file-expect-$sr_exp
1689 directives="%expect $sr_exp"
1690 fi
1691 if test -n "$rr_exp_i"; then
1692 rr_exp=$rr_exp_i
1693 file=$file-expect-rr-$rr_exp
1694 directives="$directives %expect-rr $rr_exp"
1695 fi
1696 file=$file.y
1697 echo "$directives" > $file
1698 cat $gram.y >> $file
1699
1700 # Number of found conflicts.
1701 case $gram in
1702 (sr) sr_count=1; rr_count=0;;
1703 (rr) sr_count=0; rr_count=1;;
1704 (sr-rr) sr_count=1; rr_count=1;;
1705 esac
1706
1707 # Update number of expected conflicts: if %expect is given then
1708 # %expect-rr defaults to 0, and vice-versa. Leave empty if
1709 # nothing expected.
1710 case $sr_exp_i:$rr_exp_i in
1711 ?:) rr_exp_i=0;;
1712 :?) sr_exp_i=0;;
1713 esac
1714
1715 # Run tests.
1716 if test $sr_count -eq $sr_exp && test $rr_count -eq $rr_exp; then
1717 ]AT_BISON_CHECK([[-Wnone $file]])[
1718 ]AT_BISON_CHECK([[-Werror $file]])[
1719 else
1720 {
1721 if test -z "$sr_exp_i" && test "$sr_count" -ne 0; then
1722 echo "warning: $sr_count shift/reduce conflicts"
1723 elif test "$sr_exp_i" -ne "$sr_count"; then
1724 echo "error: shift/reduce conflicts: $sr_count found, $sr_exp_i expected"
1725 fi
1726 if test -z "$rr_exp_i" && test "$rr_count" -ne 0; then
1727 echo "warning: $rr_count reduce/reduce conflicts"
1728 elif test "$rr_exp_i" -ne "$rr_count"; then
1729 echo "error: reduce/reduce conflicts: $rr_count found, $rr_exp_i expected"
1730 fi
1731 } | sed -e "s/^/$file: /" > experr
1732 ]AT_BISON_CHECK([[-Wnone $file]], [[1]], [[]], [[experr]])[
1733 ]AT_BISON_CHECK([[-Werror $file]], [[1]], [[]], [[experr]])[
1734 fi
1735 done
1736 done
1737 done]
1738
1739 AT_CLEANUP