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