]> git.saurik.com Git - bison.git/blame - tests/reduce.at
build: use gnulib's new bootstrap_sync option.
[bison.git] / tests / reduce.at
CommitLineData
cb4956ee 1# Exercising Bison Grammar Reduction. -*- Autotest -*-
7d424de1
PE
2
3# Copyright (C) 2001, 2002, 2007, 2008, 2009, 2010 Free Software
4# Foundation, Inc.
cb4956ee 5
f16b0819 6# This program is free software: you can redistribute it and/or modify
cb4956ee 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#
cb4956ee
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#
cb4956ee 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/>.
cb4956ee
AD
18
19AT_BANNER([[Grammar Reduction.]])
20
21
22## ------------------- ##
23## Useless Terminals. ##
24## ------------------- ##
25
26AT_SETUP([Useless Terminals])
27
28AT_DATA([[input.y]],
29[[%verbose
02975b9a 30%output "input.c"
cb4956ee
AD
31
32%token useless1
33%token useless2
34%token useless3
35%token useless4
36%token useless5
37%token useless6
38%token useless7
39%token useless8
40%token useless9
41
42%token useful
43%%
44exp: useful;
45]])
46
da730230 47AT_BISON_CHECK([[input.y]])
cb4956ee
AD
48
49AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
d80fb37a 50[[Terminals unused in grammar
cb4956ee
AD
51 useless1
52 useless2
53 useless3
54 useless4
55 useless5
56 useless6
57 useless7
58 useless8
59 useless9
60]])
61
62AT_CLEANUP
63
64
65
66## ---------------------- ##
67## Useless Nonterminals. ##
68## ---------------------- ##
69
70AT_SETUP([Useless Nonterminals])
71
72AT_DATA([[input.y]],
73[[%verbose
02975b9a 74%output "input.c"
cb4956ee
AD
75
76%nterm useless1
77%nterm useless2
78%nterm useless3
79%nterm useless4
80%nterm useless5
81%nterm useless6
82%nterm useless7
83%nterm useless8
84%nterm useless9
85
86%token useful
87%%
88exp: useful;
89]])
90
da730230 91AT_BISON_CHECK([[input.y]], 0, [],
cff03fb2
JD
92[[input.y: warning: 9 nonterminals useless in grammar
93input.y:4.8-15: warning: nonterminal useless in grammar: useless1
94input.y:5.8-15: warning: nonterminal useless in grammar: useless2
95input.y:6.8-15: warning: nonterminal useless in grammar: useless3
96input.y:7.8-15: warning: nonterminal useless in grammar: useless4
97input.y:8.8-15: warning: nonterminal useless in grammar: useless5
98input.y:9.8-15: warning: nonterminal useless in grammar: useless6
99input.y:10.8-15: warning: nonterminal useless in grammar: useless7
100input.y:11.8-15: warning: nonterminal useless in grammar: useless8
101input.y:12.8-15: warning: nonterminal useless in grammar: useless9
760b53a8 102]])
cb4956ee
AD
103
104AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
cff03fb2 105[[Nonterminals useless in grammar
cb4956ee
AD
106 useless1
107 useless2
108 useless3
109 useless4
110 useless5
111 useless6
112 useless7
113 useless8
114 useless9
115]])
116
117AT_CLEANUP
68f1e3ed
AD
118
119
120
121## --------------- ##
122## Useless Rules. ##
123## --------------- ##
124
125AT_SETUP([Useless Rules])
126
9757c359
AD
127AT_KEYWORDS([report])
128
68f1e3ed
AD
129AT_DATA([[input.y]],
130[[%verbose
02975b9a 131%output "input.c"
68f1e3ed
AD
132%token useful
133%%
134exp: useful;
135useless1: '1';
136useless2: '2';
137useless3: '3';
138useless4: '4';
139useless5: '5';
140useless6: '6';
141useless7: '7';
142useless8: '8';
143useless9: '9';
144]])
145
da730230 146AT_BISON_CHECK([[input.y]], 0, [],
bcf07cb7
JD
147[[input.y: warning: 9 nonterminals useless in grammar
148input.y: warning: 9 rules useless in grammar
cff03fb2
JD
149input.y:6.1-8: warning: nonterminal useless in grammar: useless1
150input.y:7.1-8: warning: nonterminal useless in grammar: useless2
151input.y:8.1-8: warning: nonterminal useless in grammar: useless3
152input.y:9.1-8: warning: nonterminal useless in grammar: useless4
153input.y:10.1-8: warning: nonterminal useless in grammar: useless5
154input.y:11.1-8: warning: nonterminal useless in grammar: useless6
155input.y:12.1-8: warning: nonterminal useless in grammar: useless7
156input.y:13.1-8: warning: nonterminal useless in grammar: useless8
157input.y:14.1-8: warning: nonterminal useless in grammar: useless9
158input.y:6.11-13: warning: rule useless in grammar: useless1: '1'
159input.y:7.11-13: warning: rule useless in grammar: useless2: '2'
160input.y:8.11-13: warning: rule useless in grammar: useless3: '3'
161input.y:9.11-13: warning: rule useless in grammar: useless4: '4'
162input.y:10.11-13: warning: rule useless in grammar: useless5: '5'
163input.y:11.11-13: warning: rule useless in grammar: useless6: '6'
164input.y:12.11-13: warning: rule useless in grammar: useless7: '7'
165input.y:13.11-13: warning: rule useless in grammar: useless8: '8'
166input.y:14.11-13: warning: rule useless in grammar: useless9: '9'
68f1e3ed
AD
167]])
168
169AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
cff03fb2 170[[Nonterminals useless in grammar
68f1e3ed
AD
171 useless1
172 useless2
173 useless3
174 useless4
175 useless5
176 useless6
177 useless7
178 useless8
179 useless9
d80fb37a 180Terminals unused in grammar
68f1e3ed
AD
181 '1'
182 '2'
183 '3'
184 '4'
185 '5'
186 '6'
187 '7'
188 '8'
189 '9'
cff03fb2 190Rules useless in grammar
9757c359
AD
191 2 useless1: '1'
192 3 useless2: '2'
193 4 useless3: '3'
194 5 useless4: '4'
195 6 useless5: '5'
196 7 useless6: '6'
197 8 useless7: '7'
198 9 useless8: '8'
199 10 useless9: '9'
68f1e3ed
AD
200]])
201
202AT_CLEANUP
203
204
205
c3b407f4
AD
206## ------------------- ##
207## Reduced Automaton. ##
208## ------------------- ##
209
210# Check that the automaton is that as the for the grammar reduced by
211# hand.
212
213AT_SETUP([Reduced Automaton])
214
9757c359
AD
215AT_KEYWORDS([report])
216
c3b407f4
AD
217# The non reduced grammar.
218# ------------------------
219AT_DATA([[not-reduced.y]],
220[[/* A useless token. */
221%token useless_token
222/* A useful one. */
223%token useful
224%verbose
02975b9a 225%output "not-reduced.c"
c3b407f4
AD
226
227%%
228
229exp: useful { /* A useful action. */ }
230 | non_productive { /* A non productive action. */ }
231 ;
232
233not_reachable: useful { /* A not reachable action. */ }
234 ;
235
236non_productive: non_productive useless_token
237 { /* Another non productive action. */ }
238 ;
e9955c83 239%%
c3b407f4
AD
240]])
241
da730230 242AT_BISON_CHECK([[not-reduced.y]], 0, [],
bcf07cb7
JD
243[[not-reduced.y: warning: 2 nonterminals useless in grammar
244not-reduced.y: warning: 3 rules useless in grammar
cff03fb2
JD
245not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable
246not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive
247not-reduced.y:11.6-57: warning: rule useless in grammar: exp: non_productive
248not-reduced.y:14.16-56: warning: rule useless in grammar: not_reachable: useful
249not-reduced.y:17.17-18.63: warning: rule useless in grammar: non_productive: non_productive useless_token
c3b407f4
AD
250]])
251
252AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
cff03fb2 253[[Nonterminals useless in grammar
c3b407f4
AD
254 not_reachable
255 non_productive
d80fb37a 256Terminals unused in grammar
c3b407f4 257 useless_token
cff03fb2 258Rules useless in grammar
9757c359
AD
259 2 exp: non_productive
260 3 not_reachable: useful
261 4 non_productive: non_productive useless_token
c3b407f4
AD
262]])
263
264# The reduced grammar.
265# --------------------
266AT_DATA([[reduced.y]],
267[[/* A useless token. */
268%token useless_token
269/* A useful one. */
270%token useful
271%verbose
02975b9a 272%output "reduced.c"
c3b407f4
AD
273
274%%
275
276exp: useful { /* A useful action. */ }
277// | non_productive { /* A non productive action. */ } */
278 ;
279
280//not_reachable: useful { /* A not reachable action. */ }
281// ;
282
283//non_productive: non_productive useless_token
284// { /* Another non productive action. */ }
285// ;
e9955c83 286%%
c3b407f4
AD
287]])
288
da730230 289AT_BISON_CHECK([[reduced.y]])
c3b407f4
AD
290
291# Comparing the parsers.
292cp reduced.c expout
293AT_CHECK([sed 's/not-reduced/reduced/g' not-reduced.c], 0, [expout])
294
295AT_CLEANUP
296
297
298
68f1e3ed
AD
299## ------------------- ##
300## Underivable Rules. ##
301## ------------------- ##
302
303AT_SETUP([Underivable Rules])
304
9757c359
AD
305AT_KEYWORDS([report])
306
68f1e3ed
AD
307AT_DATA([[input.y]],
308[[%verbose
02975b9a 309%output "input.c"
68f1e3ed
AD
310%token useful
311%%
312exp: useful | underivable;
313underivable: indirection;
314indirection: underivable;
315]])
316
da730230 317AT_BISON_CHECK([[input.y]], 0, [],
bcf07cb7
JD
318[[input.y: warning: 2 nonterminals useless in grammar
319input.y: warning: 3 rules useless in grammar
cff03fb2
JD
320input.y:5.15-25: warning: nonterminal useless in grammar: underivable
321input.y:6.14-24: warning: nonterminal useless in grammar: indirection
322input.y:5.15-25: warning: rule useless in grammar: exp: underivable
323input.y:6.14-24: warning: rule useless in grammar: underivable: indirection
324input.y:7.14-24: warning: rule useless in grammar: indirection: underivable
68f1e3ed
AD
325]])
326
327AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
cff03fb2 328[[Nonterminals useless in grammar
68f1e3ed
AD
329 underivable
330 indirection
cff03fb2 331Rules useless in grammar
9757c359
AD
332 2 exp: underivable
333 3 underivable: indirection
334 4 indirection: underivable
68f1e3ed
AD
335]])
336
337AT_CLEANUP
1bfb97db
AD
338
339
340
341## ---------------- ##
342## Empty Language. ##
343## ---------------- ##
344
345AT_SETUP([Empty Language])
346
347AT_DATA([[input.y]],
02975b9a 348[[%output "input.c"
1bfb97db
AD
349%%
350exp: exp;
351]])
352
da730230 353AT_BISON_CHECK([[input.y]], 1, [],
bcf07cb7
JD
354[[input.y: warning: 2 nonterminals useless in grammar
355input.y: warning: 2 rules useless in grammar
1bfb97db
AD
356input.y:3.1-3: fatal error: start symbol exp does not derive any sentence
357]])
358
359AT_CLEANUP
7254f6a8
JD
360
361
362
db34f798
JD
363## ----------------- ##
364## %define lr.type. ##
365## ----------------- ##
366
367# AT_TEST_LR_TYPE(DESCRIPTION,
368# DECLS, GRAMMAR, INPUT,
369# BISON-STDERR, TABLES,
370# [OTHER-CHECKS],
371# [PARSER-EXIT-VALUE],
372# [PARSER-STDOUT], [PARSER-STDERR])
373# -------------------------------------------------
374m4_define([AT_TEST_LR_TYPE],
375[
376AT_TEST_TABLES_AND_PARSE([[no %define lr.type: ]$1],
377 [[LALR]], [[]],
378 [$2], m4_shiftn(2, $@))
cf499cff 379AT_TEST_TABLES_AND_PARSE([[%define lr.type lalr: ]$1],
db34f798 380 [[LALR]], [[]],
cf499cff 381 [[%define lr.type lalr
db34f798
JD
382]$2],
383 m4_shiftn(2, $@))
cf499cff 384AT_TEST_TABLES_AND_PARSE([[%define lr.type ielr: ]$1],
db34f798 385 [[IELR]], [[]],
cf499cff 386 [[%define lr.type ielr
db34f798
JD
387]$2],
388 m4_shiftn(2, $@))
cf499cff 389AT_TEST_TABLES_AND_PARSE([[%define lr.type canonical-lr: ]$1],
db34f798 390 [[canonical LR]], [[]],
cf499cff 391 [[%define lr.type canonical-lr
db34f798
JD
392]$2],
393 m4_shiftn(2, $@))
394])
395
396AT_TEST_LR_TYPE([[Single State Split]],
397[[%left 'a'
398// Conflict resolution renders state 12 unreachable for canonical LR(1). We
399// keep it so that the paser table diff is easier to code.
67212941 400%define lr.keep-unreachable-states]],
db34f798
JD
401[[
402S: 'a' A 'a' /* rule 1 */
403 | 'b' A 'b' /* rule 2 */
404 | 'c' c /* rule 3 */
405 ;
406
407/* A conflict should appear after the first 'a' in rules 4 and 5 but only after
408 having shifted the first 'a' in rule 1. However, when LALR(1) merging is
409 chosen, the state containing that conflict is reused after having seen the
410 first 'b' in rule 2 and then the first 'a' in rules 4 and 5. In both cases,
411 because of the merged state, if the next token is an 'a', the %left forces a
412 reduction action with rule 5. In the latter case, only a shift is actually
413 grammatically correct. Thus, the parser would report a syntax error for the
414 grammatically correct sentence "baab" because it would encounter a syntax
415 error after that incorrect reduction.
416
417 Despite not being LALR(1), Menhir version 20070322 suffers from this problem
418 as well. It uses David Pager's weak compatibility test for merging states.
419 Bison and Menhir accept non-LR(1) grammars with conflict resolution. Pager
420 designed his algorithm only for LR(1) grammars. */
421A: 'a' 'a' /* rule 4 */
422 | 'a' /* rule 5 */
423 ;
424
425/* Rule 3, rule 6, and rule 7 ensure that Bison does not report rule 4 as
426 useless after conflict resolution. This proves that, even though LALR(1)
427 generates incorrect parser tables sometimes, Bison will not necessarily
428 produce any warning to help the user realize it. */
429c: 'a' 'b' /* rule 6 */
430 | A /* rule 7 */
431 ;
432]],
433
434dnl INPUT
435[['b', 'a', 'a', 'b']],
436
437dnl BISON-STDERR
438[],
439
440dnl TABLES
441[[state 0
442
443 0 $accept: . S $end
444 1 S: . 'a' A 'a'
445 2 | . 'b' A 'b'
446 3 | . 'c' c
447
448 'a' shift, and go to state 1
449 'b' shift, and go to state 2
450 'c' shift, and go to state 3
451
452 S go to state 4
453
454
455state 1
456
457 1 S: 'a' . A 'a'
458 4 A: . 'a' 'a'
459 5 | . 'a'
460
461 'a' shift, and go to state 5
462
463 A go to state 6
464
465
466state 2
467
468 2 S: 'b' . A 'b'
469 4 A: . 'a' 'a'
470 5 | . 'a'
471
472 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[16]])[
473
474 A go to state 7
475
476
477state 3
478
479 3 S: 'c' . c
480 4 A: . 'a' 'a'
481 5 | . 'a'
482 6 c: . 'a' 'b'
483 7 | . A
484
485 'a' shift, and go to state 8
486
487 A go to state 9
488 c go to state 10
489
490
491state 4
492
493 0 $accept: S . $end
494
495 $end shift, and go to state 11
496
497
498state 5
499
500 4 A: 'a' . 'a'
501 5 | 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
502
503 ]AT_COND_CASE([[canonical LR]], [['a']],
504 [[$default]])[ reduce using rule 5 (A)
505
506 Conflict between rule 5 and token 'a' resolved as reduce (%left 'a').
507
508
509state 6
510
511 1 S: 'a' A . 'a'
512
513 'a' shift, and go to state 13
514
515
516state 7
517
518 2 S: 'b' A . 'b'
519
520 'b' shift, and go to state 14
521
522
523state 8
524
525 4 A: 'a' . 'a'
526 5 | 'a' . [$end]
527 6 c: 'a' . 'b'
528
529 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[17]],
530 [[12]])[
531 'b' shift, and go to state 15
532
533 ]AT_COND_CASE([[canonical LR]], [[$end]],
534 [[$default]])[ reduce using rule 5 (A)
535
536
537state 9
538
539 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
540
541 ]AT_COND_CASE([[canonical LR]], [[$end]],
542 [[$default]])[ reduce using rule 7 (c)
543
544
545state 10
546
547 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
548
549 ]AT_COND_CASE([[canonical LR]], [[$end]],
550 [[$default]])[ reduce using rule 3 (S)
551
552
553state 11
554
555 0 $accept: S $end .
556
557 $default accept
558
559
560state 12
561
562 4 A: 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
563
564 ]AT_COND_CASE([[canonical LR]], [['a']],
565 [[$default]])[ reduce using rule 4 (A)
566
567
568state 13
569
570 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
571
572 ]AT_COND_CASE([[canonical LR]], [[$end]],
573 [[$default]])[ reduce using rule 1 (S)
574
575
576state 14
577
578 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
579
580 ]AT_COND_CASE([[canonical LR]], [[$end]],
581 [[$default]])[ reduce using rule 2 (S)
582
583
584state 15
585
586 6 c: 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
587
588 ]AT_COND_CASE([[canonical LR]], [[$end]],
589 [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]],
590 [[]], [[
591
592
593state 16
594
595 4 A: 'a' . 'a'
596 5 | 'a' . ['b']
597
598 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[18]],
599 [[12]])[
600
601 ]AT_COND_CASE([[canonical LR]], [['b']],
602 [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[
603
604
605state 17
606
607 4 A: 'a' 'a' . [$end]
608
609 $end reduce using rule 4 (A)
610
611
612state 18
613
614 4 A: 'a' 'a' . ['b']
615
616 'b' reduce using rule 4 (A)]])])[
617]],
618
619dnl OTHER-CHECKS
620[],
621
622dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
623[AT_COND_CASE([[LALR]], [[1]], [[0]])],
624[],
625[AT_COND_CASE([[LALR]],
626[[syntax error
627]])])
628
629AT_TEST_LR_TYPE([[Lane Split]],
630[[%left 'a'
631// Conflict resolution renders state 16 unreachable for canonical LR(1). We
632// keep it so that the paser table diff is easier to code.
67212941 633%define lr.keep-unreachable-states]],
db34f798
JD
634[[
635/* Similar to the last test case set but two states must be split. */
636S: 'a' A 'a' /* rule 1 */
637 | 'b' A 'b' /* rule 2 */
638 | 'c' c /* rule 3 */
639 ;
640
641A: 'a' 'a' 'a' /* rule 4 */
642 | 'a' 'a' /* rule 5 */
643 ;
644
645c: 'a' 'a' 'b' /* rule 6 */
646 | A /* rule 7 */
647 ;
648]],
649
650dnl INPUT
651[['b', 'a', 'a', 'a', 'b']],
652
653dnl BISON-STDERR
654[],
655
656dnl TABLES
657[[state 0
658
659 0 $accept: . S $end
660 1 S: . 'a' A 'a'
661 2 | . 'b' A 'b'
662 3 | . 'c' c
663
664 'a' shift, and go to state 1
665 'b' shift, and go to state 2
666 'c' shift, and go to state 3
667
668 S go to state 4
669
670
671state 1
672
673 1 S: 'a' . A 'a'
674 4 A: . 'a' 'a' 'a'
675 5 | . 'a' 'a'
676
677 'a' shift, and go to state 5
678
679 A go to state 6
680
681
682state 2
683
684 2 S: 'b' . A 'b'
685 4 A: . 'a' 'a' 'a'
686 5 | . 'a' 'a'
687
688 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[18]])[
689
690 A go to state 7
691
692
693state 3
694
695 3 S: 'c' . c
696 4 A: . 'a' 'a' 'a'
697 5 | . 'a' 'a'
698 6 c: . 'a' 'a' 'b'
699 7 | . A
700
701 'a' shift, and go to state 8
702
703 A go to state 9
704 c go to state 10
705
706
707state 4
708
709 0 $accept: S . $end
710
711 $end shift, and go to state 11
712
713
714state 5
715
716 4 A: 'a' . 'a' 'a'
717 5 | 'a' . 'a'
718
719 'a' shift, and go to state 12
720
721
722state 6
723
724 1 S: 'a' A . 'a'
725
726 'a' shift, and go to state 13
727
728
729state 7
730
731 2 S: 'b' A . 'b'
732
733 'b' shift, and go to state 14
734
735
736state 8
737
738 4 A: 'a' . 'a' 'a'
739 5 | 'a' . 'a'
740 6 c: 'a' . 'a' 'b'
741
742 'a' shift, and go to state 15
743
744
745state 9
746
747 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
748
749 ]AT_COND_CASE([[canonical LR]], [[$end]],
750 [[$default]])[ reduce using rule 7 (c)
751
752
753state 10
754
755 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
756
757 ]AT_COND_CASE([[canonical LR]], [[$end]],
758 [[$default]])[ reduce using rule 3 (S)
759
760
761state 11
762
763 0 $accept: S $end .
764
765 $default accept
766
767
768state 12
769
770 4 A: 'a' 'a' . 'a'
771 5 | 'a' 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
772
773 ]AT_COND_CASE([[canonical LR]], [['a']],
774 [[$default]])[ reduce using rule 5 (A)
775
776 Conflict between rule 5 and token 'a' resolved as reduce (%left 'a').
777
778
779state 13
780
781 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
782
783 ]AT_COND_CASE([[canonical LR]], [[$end]],
784 [[$default]])[ reduce using rule 1 (S)
785
786
787state 14
788
789 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
790
791 ]AT_COND_CASE([[canonical LR]], [[$end]],
792 [[$default]])[ reduce using rule 2 (S)
793
794
795state 15
796
797 4 A: 'a' 'a' . 'a'
798 5 | 'a' 'a' . [$end]
799 6 c: 'a' 'a' . 'b'
800
801 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[19]],
802 [[16]])[
803 'b' shift, and go to state 17
804
805 ]AT_COND_CASE([[canonical LR]], [[$end]],
806 [[$default]])[ reduce using rule 5 (A)
807
808
809state 16
810
811 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
812
813 ]AT_COND_CASE([[canonical LR]], [['a']],
814 [[$default]])[ reduce using rule 4 (A)
815
816
817state 17
818
819 6 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
820
821 ]AT_COND_CASE([[canonical LR]], [[$end]],
822 [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]],
823 [[]], [[
824
825
826state 18
827
828 4 A: 'a' . 'a' 'a'
829 5 | 'a' . 'a'
830
831 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
832 [[19]])[
833
834
835state 19]AT_COND_CASE([[canonical LR]], [[
836
837 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
838
839 ]AT_COND_CASE([[canonical LR]], [[$end]],
840 [[$default]])[ reduce using rule 4 (A)
841
842
843state 20]])[
844
845 4 A: 'a' 'a' . 'a'
846 5 | 'a' 'a' . ['b']
847
848 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]],
849 [[16]])[
850
851 ]AT_COND_CASE([[canonical LR]], [['b']],
852 [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[
853
854
855state 21
856
857 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['b']]])[
858
859 ]AT_COND_CASE([[canonical LR]], [['b']],
860 [[$default]])[ reduce using rule 4 (A)]])])[
861]],
862
863dnl OTHER-CHECKS
864[],
865
866dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
867[AT_COND_CASE([[LALR]], [[1]], [[0]])],
868[],
869[AT_COND_CASE([[LALR]],
870[[syntax error
871]])])
872
873AT_TEST_LR_TYPE([[Complex Lane Split]],
874[[%left 'a'
875// Conflict resolution renders state 16 unreachable for canonical LR(1). We
876// keep it so that the paser table diff is easier to code.
67212941 877%define lr.keep-unreachable-states]],
db34f798
JD
878[[
879/* Similar to the last test case set but forseeing the S/R conflict from the
880 first state that must be split is becoming difficult. Imagine if B were
881 even more complex. Imagine if A had other RHS's ending in other
882 nonterminals. */
883S: 'a' A 'a'
884 | 'b' A 'b'
885 | 'c' c
886 ;
887A: 'a' 'a' B
888 ;
889B: 'a'
890 | %prec 'a'
891 ;
892c: 'a' 'a' 'b'
893 | A
894 ;
895]],
896
897dnl INPUT
898[['b', 'a', 'a', 'a', 'b']],
899
900dnl BISON-STDERR
901[],
902
903dnl TABLES
904[[state 0
905
906 0 $accept: . S $end
907 1 S: . 'a' A 'a'
908 2 | . 'b' A 'b'
909 3 | . 'c' c
910
911 'a' shift, and go to state 1
912 'b' shift, and go to state 2
913 'c' shift, and go to state 3
914
915 S go to state 4
916
917
918state 1
919
920 1 S: 'a' . A 'a'
921 4 A: . 'a' 'a' B
922
923 'a' shift, and go to state 5
924
925 A go to state 6
926
927
928state 2
929
930 2 S: 'b' . A 'b'
931 4 A: . 'a' 'a' B
932
933 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[19]])[
934
935 A go to state 7
936
937
938state 3
939
940 3 S: 'c' . c
941 4 A: . 'a' 'a' B
942 7 c: . 'a' 'a' 'b'
943 8 | . A
944
945 'a' shift, and go to state 8
946
947 A go to state 9
948 c go to state 10
949
950
951state 4
952
953 0 $accept: S . $end
954
955 $end shift, and go to state 11
956
957
958state 5
959
960 4 A: 'a' . 'a' B
961
962 'a' shift, and go to state 12
963
964
965state 6
966
967 1 S: 'a' A . 'a'
968
969 'a' shift, and go to state 13
970
971
972state 7
973
974 2 S: 'b' A . 'b'
975
976 'b' shift, and go to state 14
977
978
979state 8
980
981 4 A: 'a' . 'a' B
982 7 c: 'a' . 'a' 'b'
983
984 'a' shift, and go to state 15
985
986
987state 9
988
989 8 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
990
991 ]AT_COND_CASE([[canonical LR]], [[$end]],
992 [[$default]])[ reduce using rule 8 (c)
993
994
995state 10
996
997 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
998
999 ]AT_COND_CASE([[canonical LR]], [[$end]],
1000 [[$default]])[ reduce using rule 3 (S)
1001
1002
1003state 11
1004
1005 0 $accept: S $end .
1006
1007 $default accept
1008
1009
1010state 12
1011
1012 4 A: 'a' 'a' . B
1013 5 B: . 'a'
1014 6 | . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
1015
1016 ]AT_COND_CASE([[canonical LR]], [['a']],
1017 [[$default]])[ reduce using rule 6 (B)
1018
1019 B go to state 17
1020
1021 Conflict between rule 6 and token 'a' resolved as reduce (%left 'a').
1022
1023
1024state 13
1025
1026 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1027
1028 ]AT_COND_CASE([[canonical LR]], [[$end]],
1029 [[$default]])[ reduce using rule 1 (S)
1030
1031
1032state 14
1033
1034 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1035
1036 ]AT_COND_CASE([[canonical LR]], [[$end]],
1037 [[$default]])[ reduce using rule 2 (S)
1038
1039
1040state 15
1041
1042 4 A: 'a' 'a' . B
1043 5 B: . 'a'
1044 6 | . [$end]
1045 7 c: 'a' 'a' . 'b'
1046
1047 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
1048 [[16]])[
1049 'b' shift, and go to state 18
1050
1051 ]AT_COND_CASE([[canonical LR]], [[$end]],
1052 [[$default]])[ reduce using rule 6 (B)
1053
1054 B go to state ]AT_COND_CASE([[canonical LR]], [[21]], [[17]])[
1055
1056
1057state 16
1058
1059 5 B: 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
1060
1061 ]AT_COND_CASE([[canonical LR]], [['a']],
1062 [[$default]])[ reduce using rule 5 (B)
1063
1064
1065state 17
1066
1067 4 A: 'a' 'a' B .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[
1068
1069 ]AT_COND_CASE([[canonical LR]], [['a']],
1070 [[$default]])[ reduce using rule 4 (A)
1071
1072
1073state 18
1074
1075 7 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1076
1077 ]AT_COND_CASE([[canonical LR]], [[$end]],
1078 [[$default]])[ reduce using rule 7 (c)]AT_COND_CASE([[LALR]], [], [[
1079
1080
1081state 19
1082
1083 4 A: 'a' . 'a' B
1084
1085 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[22]],
1086 [[20]])[
1087
1088
1089state 20]AT_COND_CASE([[canonical LR]], [[
1090
1091 5 B: 'a' . [$end]
1092
1093 $end reduce using rule 5 (B)
1094
1095
1096state 21
1097
1098 4 A: 'a' 'a' B . [$end]
1099
1100 $end reduce using rule 4 (A)
1101
1102
1103state 22]])[
1104
1105 4 A: 'a' 'a' . B
1106 5 B: . 'a'
1107 6 | . ['b']
1108
1109 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[23]],
1110 [[16]])[
1111
1112 ]AT_COND_CASE([[canonical LR]], [['b']],
1113 [[$default]])[ reduce using rule 6 (B)
1114
1115 B go to state ]AT_COND_CASE([[canonical LR]], [[24
1116
1117
1118state 23
1119
1120 5 B: 'a' . ['b']
1121
1122 'b' reduce using rule 5 (B)
1123
1124
1125state 24
1126
1127 4 A: 'a' 'a' B . ['b']
1128
1129 'b' reduce using rule 4 (A)]], [[17]])])[
1130]],
1131
1132dnl OTHER-CHECKS
1133[],
1134
1135dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
1136[AT_COND_CASE([[LALR]], [[1]], [[0]])],
1137[],
1138[AT_COND_CASE([[LALR]],
1139[[syntax error
1140]])])
1141
1142AT_TEST_LR_TYPE([[Split During Added Lookahead Propagation]],
67212941 1143[[%define lr.keep-unreachable-states]],
db34f798
JD
1144[[
1145/* The partial state chart diagram below is for LALR(1). State 0 is the start
1146 state. States are iterated for successor construction in numerical order.
1147 Transitions are downwards.
1148
1149 State 13 has a R/R conflict that cannot be predicted by Bison's LR(1)
1150 algorithm using annotations alone. That is, when state 11's successor on
1151 'd' is merged with state 5 (which is originally just state 1's successor on
1152 'd'), state 5's successor on 'e' must then be changed because the resulting
1153 lookaheads that propagate to it now make it incompatible with state 8's
1154 successor on 'e'. In other words, state 13 must be split to avoid the
1155 conflict.
1156
1157 0
1158 / | \
1159 a / c| \ b
1160 1 3 2
1161 | | |
1162 d| |c | d
1163 | 11 |
1164 | | |
1165 \ /d |
1166 5 8
1167 \ |
1168 e \ / e
1169 13
1170 R/R
1171
1172 This grammar is designed carefully to make sure that, despite Bison's LR(1)
1173 algorithm's bread-first iteration of transitions to reconstruct states,
1174 state 11's successors are constructed after state 5's and state 8's.
1175 Otherwise (for example, if you remove the first 'c' in each of rules 6 and
1176 7), state 5's successor on 'e' would never be merged with state 8's, so the
1177 split of the resulting state 13 would never need to be performed. */
1178S: 'a' A 'f'
1179 | 'a' B
1180 | 'b' A 'f'
1181 | 'b' B 'g'
1182 | 'b' 'd'
1183 | 'c' 'c' A 'g'
1184 | 'c' 'c' B
1185 ;
1186A: 'd' 'e' ;
1187B: 'd' 'e' ;
1188]],
1189
1190dnl INPUT
1191[['b', 'd', 'e', 'g']],
1192
1193dnl BISON-STDERR
1194[AT_COND_CASE([[LALR]],
1195[[input.y: conflicts: 1 reduce/reduce
1196]], [])],
1197
1198dnl TABLES
1199[[state 0
1200
1201 0 $accept: . S $end
1202 1 S: . 'a' A 'f'
1203 2 | . 'a' B
1204 3 | . 'b' A 'f'
1205 4 | . 'b' B 'g'
1206 5 | . 'b' 'd'
1207 6 | . 'c' 'c' A 'g'
1208 7 | . 'c' 'c' B
1209
1210 'a' shift, and go to state 1
1211 'b' shift, and go to state 2
1212 'c' shift, and go to state 3
1213
1214 S go to state 4
1215
1216
1217state 1
1218
1219 1 S: 'a' . A 'f'
1220 2 | 'a' . B
1221 8 A: . 'd' 'e'
1222 9 B: . 'd' 'e'
1223
1224 'd' shift, and go to state 5
1225
1226 A go to state 6
1227 B go to state 7
1228
1229
1230state 2
1231
1232 3 S: 'b' . A 'f'
1233 4 | 'b' . B 'g'
1234 5 | 'b' . 'd'
1235 8 A: . 'd' 'e'
1236 9 B: . 'd' 'e'
1237
1238 'd' shift, and go to state 8
1239
1240 A go to state 9
1241 B go to state 10
1242
1243
1244state 3
1245
1246 6 S: 'c' . 'c' A 'g'
1247 7 | 'c' . 'c' B
1248
1249 'c' shift, and go to state 11
1250
1251
1252state 4
1253
1254 0 $accept: S . $end
1255
1256 $end shift, and go to state 12
1257
1258
1259state 5
1260
1261 8 A: 'd' . 'e'
1262 9 B: 'd' . 'e'
1263
1264 'e' shift, and go to state ]AT_COND_CASE([[LALR]], [[13]],
1265 [[canonical LR]], [[13]],
1266 [[20]])[
1267
1268
1269state 6
1270
1271 1 S: 'a' A . 'f'
1272
1273 'f' shift, and go to state 14
1274
1275
1276state 7
1277
1278 2 S: 'a' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1279
1280 ]AT_COND_CASE([[canonical LR]], [[$end]],
1281 [[$default]])[ reduce using rule 2 (S)
1282
1283
1284state 8
1285
1286 5 S: 'b' 'd' . [$end]
1287 8 A: 'd' . 'e'
1288 9 B: 'd' . 'e'
1289
1290 'e' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
1291 [[13]])[
1292
1293 ]AT_COND_CASE([[canonical LR]], [[$end]],
1294 [[$default]])[ reduce using rule 5 (S)
1295
1296
1297state 9
1298
1299 3 S: 'b' A . 'f'
1300
1301 'f' shift, and go to state 15
1302
1303
1304state 10
1305
1306 4 S: 'b' B . 'g'
1307
1308 'g' shift, and go to state 16
1309
1310
1311state 11
1312
1313 6 S: 'c' 'c' . A 'g'
1314 7 | 'c' 'c' . B
1315 8 A: . 'd' 'e'
1316 9 B: . 'd' 'e'
1317
1318 'd' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]],
1319 [[5]])[
1320
1321 A go to state 17
1322 B go to state 18
1323
1324
1325state 12
1326
1327 0 $accept: S $end .
1328
1329 $default accept]AT_COND_CASE([[LALR]], [[
1330
1331
1332state 13
1333
1334 8 A: 'd' 'e' . ['f', 'g']
1335 9 B: 'd' 'e' . [$end, 'g']
1336
1337 $end reduce using rule 9 (B)
1338 'g' reduce using rule 8 (A)
1339 'g' [reduce using rule 9 (B)]
1340 $default reduce using rule 8 (A)]], [[
1341
1342
1343state 13
1344
1345 8 A: 'd' 'e' . ['f']
1346 9 B: 'd' 'e' . ]AT_COND_CASE([[canonical LR]], [[[$end]]], [[['g']]])[
1347
1348 ]AT_COND_CASE([[canonical LR]], [[$end]],
1349 [['g' ]])[ reduce using rule 9 (B)
1350 ]AT_COND_CASE([[canonical LR]], [['f' ]],
1351 [[$default]])[ reduce using rule 8 (A)]])[
1352
1353
1354state 14
1355
1356 1 S: 'a' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1357
1358 ]AT_COND_CASE([[canonical LR]], [[$end]],
1359 [[$default]])[ reduce using rule 1 (S)
1360
1361
1362state 15
1363
1364 3 S: 'b' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1365
1366 ]AT_COND_CASE([[canonical LR]], [[$end]],
1367 [[$default]])[ reduce using rule 3 (S)
1368
1369
1370state 16
1371
1372 4 S: 'b' B 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1373
1374 ]AT_COND_CASE([[canonical LR]], [[$end]],
1375 [[$default]])[ reduce using rule 4 (S)
1376
1377
1378state 17
1379
1380 6 S: 'c' 'c' A . 'g'
1381
1382 'g' shift, and go to state 19
1383
1384
1385state 18
1386
1387 7 S: 'c' 'c' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1388
1389 ]AT_COND_CASE([[canonical LR]], [[$end]],
1390 [[$default]])[ reduce using rule 7 (S)
1391
1392
1393state 19
1394
1395 6 S: 'c' 'c' A 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[
1396
1397 ]AT_COND_CASE([[canonical LR]], [[$end]],
1398 [[$default]])[ reduce using rule 6 (S)]AT_COND_CASE([[LALR]],
1399 [[]], [[
1400
1401
1402state 20]AT_COND_CASE([[canonical LR]], [[
1403
1404 8 A: 'd' 'e' . ['f']
1405 9 B: 'd' 'e' . ['g']
1406
1407 'f' reduce using rule 8 (A)
1408 'g' reduce using rule 9 (B)
1409
1410
1411state 21
1412
1413 8 A: 'd' . 'e'
1414 9 B: 'd' . 'e'
1415
1416 'e' shift, and go to state 22
1417
1418
1419state 22
1420
1421 8 A: 'd' 'e' . ['g']
1422 9 B: 'd' 'e' . [$end]
1423
1424 $end reduce using rule 9 (B)
1425 'g' reduce using rule 8 (A)]], [[
1426
1427 8 A: 'd' 'e' . ['f', 'g']
1428 9 B: 'd' 'e' . [$end]
1429
1430 $end reduce using rule 9 (B)
1431 $default reduce using rule 8 (A)]])])[
1432]],
1433
1434dnl OTHER-CHECKS
1435[],
1436
1437dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR
1438[AT_COND_CASE([[LALR]], [[1]], [[0]])],
1439[],
1440[AT_COND_CASE([[LALR]],
1441[[syntax error
1442]])])
1443
1444
1445
110ef36a 1446## ------------------------------- ##
5bab9d08 1447## %define lr.default-reductions. ##
110ef36a 1448## ------------------------------- ##
7254f6a8 1449
110ef36a
JD
1450# AT_TEST_LR_DEFAULT_REDUCTIONS(GRAMMAR, INPUT, TABLES)
1451# -----------------------------------------------------
1452m4_define([AT_TEST_LR_DEFAULT_REDUCTIONS],
7254f6a8 1453[
5bab9d08 1454AT_TEST_TABLES_AND_PARSE([[no %define lr.default-reductions]],
7254f6a8
JD
1455 [[all]], [[]],
1456 [[]],
1457 [$1], [$2], [[]], [$3])
cf499cff 1458AT_TEST_TABLES_AND_PARSE([[%define lr.default-reductions all]],
7254f6a8 1459 [[all]], [[]],
cf499cff 1460 [[%define lr.default-reductions all]],
7254f6a8 1461 [$1], [$2], [[]], [$3])
cf499cff 1462AT_TEST_TABLES_AND_PARSE([[%define lr.default-reductions consistent]],
7254f6a8 1463 [[consistent]], [[]],
cf499cff 1464 [[%define lr.default-reductions consistent]],
7254f6a8 1465 [$1], [$2], [[]], [$3])
cf499cff 1466AT_TEST_TABLES_AND_PARSE([[%define lr.default-reductions accepting]],
7254f6a8 1467 [[accepting]], [[]],
cf499cff 1468 [[%define lr.default-reductions accepting]],
7254f6a8
JD
1469 [$1], [$2], [[]], [$3])
1470])
1471
110ef36a 1472AT_TEST_LR_DEFAULT_REDUCTIONS([[
7254f6a8
JD
1473/* The start state is consistent and has a shift on 'a' and no reductions.
1474 After pushing the b below, enter an inconsistent state that has a shift and
1475 one reduction with one lookahead. */
1476start:
1477 a b
1478 | a b 'a'
1479 | a c 'b'
1480 ;
1481
1482/* After shifting this 'a', enter a consistent state that has no shift and 1
1483 reduction with multiple lookaheads. */
1484a: 'a' ;
1485
1486/* After the previous reduction, enter an inconsistent state that has no shift
1487 and multiple reductions. The first reduction has more lookaheads than the
110ef36a 1488 second, so the first should always be preferred as the default reduction if
7254f6a8
JD
1489 enabled. The second reduction has one lookahead. */
1490b: ;
1491c: ;
1492]],
1493dnl Visit each state mentioned above.
1494[['a', 'a']],
1495[[state 0
1496
1497 0 $accept: . start $end
1498 1 start: . a b
1499 2 | . a b 'a'
1500 3 | . a c 'b'
1501 4 a: . 'a'
1502
1503 'a' shift, and go to state 1
1504
1505 start go to state 2
1506 a go to state 3
1507
1508
1509state 1
1510
1511 4 a: 'a' .]AT_COND_CASE([[accepting]], [[ [$end, 'a', 'b']
1512
1513 $end reduce using rule 4 (a)
1514 'a' reduce using rule 4 (a)
1515 'b' reduce using rule 4 (a)]], [[
1516
1517 $default reduce using rule 4 (a)]])[
1518
1519
1520state 2
1521
1522 0 $accept: start . $end
1523
1524 $end shift, and go to state 4
1525
1526
1527state 3
1528
1529 1 start: a . b
1530 2 | a . b 'a'
1531 3 | a . c 'b'
1532 5 b: . [$end, 'a']
1533 6 c: . ['b']]AT_COND_CASE([[all]], [[
1534
1535 'b' reduce using rule 6 (c)
1536 $default reduce using rule 5 (b)]], [[
1537
1538 $end reduce using rule 5 (b)
1539 'a' reduce using rule 5 (b)
1540 'b' reduce using rule 6 (c)]])[
1541
1542 b go to state 5
1543 c go to state 6
1544
1545
1546state 4
1547
1548 0 $accept: start $end .
1549
1550 $default accept
1551
1552
1553state 5
1554
1555 1 start: a b . [$end]
1556 2 | a b . 'a'
1557
1558 'a' shift, and go to state 7
1559
1560 ]AT_COND_CASE([[all]], [[$default]], [[$end]])[ reduce using rule 1 (start)
1561
1562
1563state 6
1564
1565 3 start: a c . 'b'
1566
1567 'b' shift, and go to state 8
1568
1569
1570state 7
1571
1572 2 start: a b 'a' .]AT_COND_CASE([[accepting]], [[ [$end]
1573
1574 $end reduce using rule 2 (start)]], [[
1575
1576 $default reduce using rule 2 (start)]])[
1577
1578
1579state 8
1580
1581 3 start: a c 'b' .]AT_COND_CASE([[accepting]], [[ [$end]
1582
1583 $end reduce using rule 3 (start)]], [[
1584
1585 $default reduce using rule 3 (start)]])[
1586]])