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