]> git.saurik.com Git - bison.git/blame - tests/glr-regression.at
* bootstrap.conf (gnulib_modules): Add config-h.
[bison.git] / tests / glr-regression.at
CommitLineData
ede3d3bc 1# Checking GLR Parsing: Regression Tests -*- Autotest -*-
2781dbd1 2# Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
ede3d3bc
PH
3
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 2, or (at your option)
7# any later version.
8
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
0fb669f9
PE
16# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17# 02110-1301, USA.
ede3d3bc
PH
18
19AT_BANNER([[GLR Regression Tests]])
20
21## --------------------------- ##
22## Badly Collapsed GLR States. ##
23## --------------------------- ##
24
25AT_SETUP([Badly Collapsed GLR States])
26
27AT_DATA_GRAMMAR([glr-regr1.y],
28[[/* Regression Test: Improper state compression */
29/* Reported by Scott McPeak */
30
31%{
32#include <stdio.h>
cf806753 33#include <stdlib.h>
ede3d3bc
PH
34
35#define YYSTYPE int
36static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1);
37int yylex (void);
ac8c5689 38void yyerror (char const *msg);
ede3d3bc
PH
39%}
40
41
42%glr-parser
43
44
45/* -------- productions ------ */
46%%
47
48StartSymbol: E { $$=0; } %merge <exprMerge>
49 ;
50
51E: E 'P' E { $$=1; printf("E -> E 'P' E\n"); } %merge <exprMerge>
52 | 'B' { $$=2; printf("E -> 'B'\n"); } %merge <exprMerge>
53 ;
54
55
56
57/* ---------- C code ----------- */
58%%
59
60static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1)
61{
62 (void) x0;
63 (void) x1;
64 printf ("<OR>\n");
65 return 0;
66}
67
68int
69main (void)
70{
71 return yyparse ();
72}
73
ac8c5689 74void
ede3d3bc
PH
75yyerror (char const *msg)
76{
77 fprintf (stderr, "%s\n", msg);
ede3d3bc
PH
78}
79
80
81int
82yylex (void)
83{
84 for (;;)
85 {
cf806753
PE
86 int ch;
87 if (feof (stdin))
88 abort ();
89 ch = getchar ();
ede3d3bc
PH
90 if (ch == EOF)
91 return 0;
92 else if (ch == 'B' || ch == 'P')
93 return ch;
94 }
95}
96]])
97
98AT_CHECK([[bison -o glr-regr1.c glr-regr1.y]], 0, [],
99[glr-regr1.y: conflicts: 1 shift/reduce
100])
101AT_COMPILE([glr-regr1])
102AT_CHECK([[echo BPBPB | ./glr-regr1]], 0,
103[[E -> 'B'
104E -> 'B'
105E -> E 'P' E
106E -> 'B'
107E -> E 'P' E
108E -> 'B'
109E -> E 'P' E
110E -> E 'P' E
111<OR>
112]], [])
113
114AT_CLEANUP
115
116## ------------------------------------------------------------ ##
117## Improper handling of embedded actions and $-N in GLR parsers ##
118## ------------------------------------------------------------ ##
119
d6d67dbd 120AT_SETUP([Improper handling of embedded actions and dollar(-N) in GLR parsers])
ede3d3bc
PH
121
122AT_DATA_GRAMMAR([glr-regr2a.y],
123[[/* Regression Test: Improper handling of embedded actions and $-N */
124/* Reported by S. Eken */
125
126%{
f5228370 127 #define YYSTYPE char *
ede3d3bc
PH
128
129 #include <ctype.h>
130 #include <stdio.h>
f508a6a0 131 #include <stdlib.h>
ede3d3bc
PH
132 #include <string.h>
133 int yylex (void);
134 void yyerror (char const *);
135%}
136
137%glr-parser
138
139%%
140
141command:
142 's' var 't'
d6d67dbd 143 { printf ("Variable: '%s'\n", $2); }
ede3d3bc 144 'v' 'x' 'q'
f5228370 145 { free ($2); }
ede3d3bc 146 | 's' var_list 't' 'e'
f5228370 147 { printf ("Varlist: '%s'\n", $2); free ($2); }
ede3d3bc 148 | 's' var 't' var_printer 'x'
f5228370 149 { free ($2); }
ede3d3bc
PH
150 ;
151
152var:
153 'V'
154 { $$ = $1; }
155 ;
156
157var_list:
158 var
159 { $$ = $1; }
160 | var ',' var_list
161 {
f5228370 162 char *s = (char *) realloc ($1, strlen ($1) + 1 + strlen ($3) + 1);
c70fdfcd
PE
163 strcat (s, ",");
164 strcat (s, $3);
f5228370 165 free ($3);
c70fdfcd 166 $$ = s;
d6d67dbd 167 }
ede3d3bc
PH
168 ;
169
170var_printer: 'v'
171 { printf ("Variable: '%s'\n", $-1); }
172
173%%
174
cf806753 175FILE *input;
ede3d3bc
PH
176
177int
178yylex (void)
d6d67dbd 179{
ede3d3bc 180 char buf[50];
c70fdfcd 181 char *s;
cf806753
PE
182 if (feof (stdin))
183 abort ();
a9739e7c 184 switch (fscanf (input, " %1[a-z,]", buf)) {
ede3d3bc
PH
185 case 1:
186 return buf[0];
187 case EOF:
188 return 0;
189 default:
190 break;
191 }
a9739e7c 192 if (fscanf (input, "%49s", buf) != 1)
ac8c5689 193 return 0;
f508a6a0
PE
194 if (sizeof buf - 1 <= strlen (buf))
195 abort ();
c70fdfcd
PE
196 s = (char *) malloc (strlen (buf) + 1);
197 strcpy (s, buf);
198 yylval = s;
ede3d3bc
PH
199 return 'V';
200}
201
202void
203yyerror (char const *s)
204{ printf ("%s\n", s);
205}
206
207int
208main (int argc, char **argv)
d6d67dbd 209{
a9739e7c
PE
210 input = stdin;
211 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
ede3d3bc
PH
212 return yyparse ();
213}
214]])
215
216AT_CHECK([[bison -o glr-regr2a.c glr-regr2a.y]], 0, [],
217[glr-regr2a.y: conflicts: 2 shift/reduce
218])
219AT_COMPILE([glr-regr2a])
220
221AT_CHECK([[echo s VARIABLE_1 t v x q | ./glr-regr2a]], 0,
222[[Variable: 'VARIABLE_1'
223]], [])
224AT_CHECK([[echo s VARIABLE_1 , ANOTHER_VARIABLE_2 t e | ./glr-regr2a]], 0,
225[[Varlist: 'VARIABLE_1,ANOTHER_VARIABLE_2'
226]])
227AT_CHECK([[echo s VARIABLE_3 t v x | ./glr-regr2a]], 0,
228[[Variable: 'VARIABLE_3'
229]], [])
230
231
5e6f62f2
PH
232AT_CLEANUP
233
234## ------------------------------------------------------------ ##
235## Improper merging of GLR delayed action sets ##
236## ------------------------------------------------------------ ##
237
238AT_SETUP([Improper merging of GLR delayed action sets])
239
240AT_DATA_GRAMMAR([glr-regr3.y],
241[[/* Regression Test: Improper merging of GLR delayed action sets. */
242/* Reported by M. Rosien */
243
244%{
245#include <stdio.h>
cf806753 246#include <stdlib.h>
5e6f62f2
PH
247#include <stdarg.h>
248
249static int MergeRule (int x0, int x1);
c66dfadd 250static void yyerror (char const * s);
1beb0b24 251int yylex (void);
5e6f62f2
PH
252
253#define RULE(x) (1 << (x))
254
255%}
256
257%glr-parser
258
259%token BAD_CHAR
260%token P1 P2 T1 T2 T3 T4 O1 O2
261
262%%
263
264S : P1 T4 O2 NT6 P2 { printf ("Result: %x\n", $4); }
265;
266
267NT1 : P1 T1 O1 T2 P2 { $$ = RULE(2); } %merge<MergeRule>
268;
269
270NT2 : NT1 { $$ = RULE(3); } %merge<MergeRule>
271 | P1 NT1 O1 T3 P2 { $$ = RULE(4); } %merge<MergeRule>
272;
273
274NT3 : T3 { $$ = RULE(5); } %merge<MergeRule>
275 | P1 NT1 O1 T3 P2 { $$ = RULE(6); } %merge<MergeRule>
276;
277
278NT4 : NT3 { $$ = RULE(7); } %merge<MergeRule>
279 | NT2 { $$ = RULE(8); } %merge<MergeRule>
280 | P1 NT2 O1 NT3 P2 { $$ = RULE(9); } %merge<MergeRule>
281;
282
283NT5 : NT4 { $$ = RULE(10); } %merge<MergeRule>
284;
285
286NT6 : P1 NT1 O1 T3 P2 { $$ = RULE(11) | $2; } %merge<MergeRule>
287 | NT5 { $$ = RULE(12) | $1; } %merge<MergeRule>
288;
289
290%%
291
292static int MergeRule (int x0, int x1) {
293 return x0 | x1;
294}
295
296static void yyerror(char const * s) {
297 fprintf(stderr,"error: %s\n",s);
298}
299
a9739e7c 300FILE *input = NULL;
5e6f62f2
PH
301
302int P[] = { P1, P2 };
303int O[] = { O1, O2 };
304int T[] = { T1, T2, T3, T4 };
305
306int yylex (void)
307{
308 char inp[3];
cf806753
PE
309 if (feof (stdin))
310 abort ();
a9739e7c 311 if (fscanf (input, "%2s", inp) == EOF)
5e6f62f2 312 return 0;
1beb0b24 313 switch (inp[0])
5e6f62f2
PH
314 {
315 case 'p': return P[inp[1] - '1'];
316 case 't': return T[inp[1] - '1'];
317 case 'o': return O[inp[1] - '1'];
318 }
319 return BAD_CHAR;
320}
321
322int main(int argc, char* argv[]) {
a9739e7c
PE
323 input = stdin;
324 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
5e6f62f2
PH
325 return yyparse ();
326}
327]])
328
329AT_CHECK([[bison -o glr-regr3.c glr-regr3.y]], 0, [],
330[glr-regr3.y: conflicts: 1 shift/reduce, 1 reduce/reduce
331])
332AT_COMPILE([glr-regr3])
333
334AT_CHECK([[echo p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2 | ./glr-regr3]], 0,
335[[Result: 1c04
336]], [])
337
ede3d3bc 338AT_CLEANUP
f9315de5
PE
339
340
4158e0a1
JD
341## ------------------------------------------------------------------------- ##
342## Duplicate representation of merged trees. See ##
343## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>. ##
344## ------------------------------------------------------------------------- ##
f9315de5
PE
345
346AT_SETUP([Duplicate representation of merged trees])
347
348AT_DATA_GRAMMAR([glr-regr4.y],
1bd0deda
PE
349[[
350%union { char *ptr; }
f9315de5
PE
351%type <ptr> S A A1 A2 B
352%glr-parser
353
354%{
355 #include <stdio.h>
356 #include <stdlib.h>
357 #include <string.h>
358 static char *merge (YYSTYPE, YYSTYPE);
1bd0deda 359 static char *make_value (char const *, char const *);
f9315de5
PE
360 static void yyerror (char const *);
361 static int yylex (void);
362%}
363
364%%
365
366tree: S { printf ("%s\n", $1); } ;
367
368S:
369 A %merge<merge> { $$ = make_value ("S", $1); }
370 | B %merge<merge> { $$ = make_value ("S", $1); }
371 ;
372
373A:
374 A1 %merge<merge> { $$ = make_value ("A", $1); }
375 | A2 %merge<merge> { $$ = make_value ("A", $1); }
376 ;
377
378A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
379A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
380B: 'a' { $$ = make_value ("B", "'a'"); } ;
381
382%%
383
384static int
385yylex (void)
386{
cf806753
PE
387 static char const input[] = "a";
388 static size_t toknum;
389 if (! (toknum < sizeof input))
390 abort ();
391 return input[toknum++];
f9315de5
PE
392}
393
394int
395main (void)
396{
397 return yyparse ();
398}
399
400static char *
1bd0deda 401make_value (char const *parent, char const *child)
f9315de5
PE
402{
403 char const format[] = "%s <- %s";
7812f299
PE
404 char *value =
405 (char *) malloc (strlen (parent) + strlen (child) + sizeof format);
f9315de5
PE
406 sprintf (value, format, parent, child);
407 return value;
408}
409
410static char *
411merge (YYSTYPE s1, YYSTYPE s2)
412{
413 char const format[] = "merge{ %s and %s }";
7812f299
PE
414 char *value =
415 (char *) malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format);
f9315de5
PE
416 sprintf (value, format, s1.ptr, s2.ptr);
417 return value;
418}
419
420static void
421yyerror (char const *msg)
422{
42a6501d 423 fprintf (stderr, "%s\n", msg);
f9315de5
PE
424}
425]])
426
427AT_CHECK([[bison -o glr-regr4.c glr-regr4.y]], 0, [],
428[glr-regr4.y: conflicts: 1 reduce/reduce
429])
430AT_COMPILE([glr-regr4])
431
432AT_CHECK([[./glr-regr4]], 0,
433[[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
434]], [])
435
436AT_CLEANUP
adc90f13
PE
437
438
4158e0a1
JD
439## -------------------------------------------------------------------------- ##
440## User destructor for unresolved GLR semantic value. See ##
441## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>. ##
442## -------------------------------------------------------------------------- ##
adc90f13
PE
443
444AT_SETUP([User destructor for unresolved GLR semantic value])
445
446AT_DATA_GRAMMAR([glr-regr5.y],
1bd0deda
PE
447[[
448%{
adc90f13
PE
449 #include <stdio.h>
450 #include <stdlib.h>
451 static void yyerror (char const *);
452 static int yylex (void);
453 enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
454%}
455
456%glr-parser
457%union { int value; }
458%type <value> start
459
460%destructor {
461 if ($$ != MAGIC_VALUE)
462 {
463 fprintf (stderr, "Bad destructor call.\n");
464 exit (EXIT_FAILURE);
465 }
466} start
467
468%%
469
470start:
471 'a' { $$ = MAGIC_VALUE; }
472 | 'a' { $$ = MAGIC_VALUE; }
473 ;
474
475%%
476
477static int
478yylex (void)
479{
cf806753
PE
480 static char const input[] = "a";
481 static size_t toknum;
482 if (! (toknum < sizeof input))
483 abort ();
484 return input[toknum++];
adc90f13
PE
485}
486
487static void
488yyerror (char const *msg)
489{
42a6501d 490 fprintf (stderr, "%s\n", msg);
adc90f13
PE
491}
492
493int
494main (void)
495{
496 return yyparse () != 1;
497}
498]])
499
500AT_CHECK([[bison -o glr-regr5.c glr-regr5.y]], 0, [],
501[glr-regr5.y: conflicts: 1 reduce/reduce
502])
503AT_COMPILE([glr-regr5])
504
42a6501d
PE
505AT_CHECK([[./glr-regr5]], 0, [],
506[syntax is ambiguous
507])
508
509AT_CLEANUP
510
511
4158e0a1
JD
512## -------------------------------------------------------------------------- ##
513## User destructor after an error during a split parse. See ##
514## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>. ##
515## -------------------------------------------------------------------------- ##
42a6501d
PE
516
517AT_SETUP([User destructor after an error during a split parse])
518
519AT_DATA_GRAMMAR([glr-regr6.y],
1bd0deda
PE
520[[
521%{
42a6501d
PE
522 #include <stdio.h>
523 #include <stdlib.h>
524 static void yyerror (char const *);
525 static int yylex (void);
526%}
527
528%glr-parser
529%union { int value; }
530%type <value> 'a'
531
532%destructor {
533 printf ("Destructor called.\n");
534} 'a'
535
536%%
537
538start: 'a' | 'a' ;
539
540%%
541
542static int
543yylex (void)
544{
cf806753
PE
545 static char const input[] = "a";
546 static size_t toknum;
547 if (! (toknum < sizeof input))
548 abort ();
549 return input[toknum++];
42a6501d
PE
550}
551
552static void
553yyerror (char const *msg)
554{
555 fprintf (stderr, "%s\n", msg);
556}
557
558int
559main (void)
560{
561 return yyparse () != 1;
562}
563]])
564
565AT_CHECK([[bison -o glr-regr6.c glr-regr6.y]], 0, [],
566[glr-regr6.y: conflicts: 1 reduce/reduce
567])
568AT_COMPILE([glr-regr6])
569
570AT_CHECK([[./glr-regr6]], 0,
571[Destructor called.
572],
adc90f13
PE
573[syntax is ambiguous
574])
575
576AT_CLEANUP
1bd0deda
PE
577
578
579## ------------------------------------------------------------------------- ##
4158e0a1 580## Duplicated user destructor for lookahead. See ##
1bd0deda
PE
581## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>. ##
582## ------------------------------------------------------------------------- ##
583
584AT_SETUP([Duplicated user destructor for lookahead])
585
586AT_DATA_GRAMMAR([glr-regr7.y],
587[[
588%{
589 #include <stdio.h>
590 #include <stdlib.h>
591 static void yyerror (char const *);
592 static int yylex (void);
593 #define YYSTACKEXPANDABLE 0
594%}
595
596%glr-parser
597%union { int *count; }
598%type <count> 'a'
599
600%destructor {
601 if ((*$$)++)
602 fprintf (stderr, "Destructor called on same value twice.\n");
603} 'a'
604
605%%
606
607start:
608 stack1 start
609 | stack2 start
610 | /* empty */
611 ;
612stack1: 'a' ;
613stack2: 'a' ;
614
615%%
616
617static int
618yylex (void)
619{
a9739e7c 620 yylval.count = (int *) malloc (sizeof (int));
1bd0deda
PE
621 if (!yylval.count)
622 {
623 fprintf (stderr, "Test inconclusive.\n");
624 exit (EXIT_FAILURE);
625 }
626 *yylval.count = 0;
627 return 'a';
628}
629
630static void
631yyerror (char const *msg)
632{
633 fprintf (stderr, "%s\n", msg);
634}
635
636int
637main (void)
638{
639 return yyparse ();
640}
641]])
642
643AT_CHECK([[bison -o glr-regr7.c glr-regr7.y]], 0, [],
644[glr-regr7.y: conflicts: 2 reduce/reduce
645])
646AT_COMPILE([glr-regr7])
647
a9739e7c 648AT_CHECK([[./glr-regr7]], 2, [],
1bd0deda
PE
649[memory exhausted
650])
651
652AT_CLEANUP
44e7ead1
PH
653
654
655## ------------------------------------------------------------------------- ##
656## Incorrect default location for empty right-hand sides. Adapted from bug ##
657## report by Claudia Hermann. ##
658## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
659## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html ##
660## ------------------------------------------------------------------------- ##
661
662AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
663
664AT_DATA_GRAMMAR([glr-regr8.y],
665[[
666%{
667 #include <stdio.h>
668 #include <stdlib.h>
669 static void yyerror (char const *);
670 static int yylex (void);
c66dfadd 671 static void yyerror (char const *msg);
44e7ead1
PH
672%}
673
674%token T_CONSTANT
675%token T_PORT
676%token T_SIGNAL
677
678%glr-parser
679
680%%
681
682
683PortClause : T_PORT InterfaceDeclaration T_PORT
69ce078b
PE
684 { printf("%d/%d - %d/%d - %d/%d\n",
685 @1.first_column, @1.last_column,
686 @2.first_column, @2.last_column,
44e7ead1
PH
687 @3.first_column, @3.last_column); }
688 ;
689
690InterfaceDeclaration : OptConstantWord %dprec 1
691 | OptSignalWord %dprec 2
692 ;
693
694OptConstantWord : /* empty */
695 | T_CONSTANT
696 ;
697
698OptSignalWord : /* empty */
699 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
700 | T_SIGNAL
701 ;
702
703%%
704
c66dfadd
PE
705void
706yyerror (char const *msg)
44e7ead1 707{
c66dfadd 708 fprintf (stderr, "%s\n", msg);
44e7ead1
PH
709}
710
711static int lexIndex;
712
69ce078b 713int yylex (void)
44e7ead1
PH
714{
715 lexIndex += 1;
716 switch (lexIndex)
717 {
cf806753
PE
718 default:
719 abort ();
44e7ead1
PH
720 case 1:
721 yylloc.first_column = 1;
722 yylloc.last_column = 9;
723 return T_PORT;
724 case 2:
725 yylloc.first_column = 13;
726 yylloc.last_column = 17;
727 return T_PORT;
cf806753 728 case 3:
44e7ead1
PH
729 return 0;
730 }
731}
732
733int
69ce078b 734main (void)
44e7ead1
PH
735{
736 yyparse();
737 return 0;
738}
739]])
740
741AT_CHECK([[bison -o glr-regr8.c glr-regr8.y]], 0, [],
742[glr-regr8.y: conflicts: 1 reduce/reduce
743])
744AT_COMPILE([glr-regr8])
745
69ce078b 746AT_CHECK([[./glr-regr8]], 0,
44e7ead1
PH
747[empty: 9/9
7481/9 - 9/9 - 13/17
749],
750[])
751
752AT_CLEANUP
69ce078b
PE
753
754
755## ------------------------------------------------------------------------- ##
4158e0a1 756## No users destructors if stack 0 deleted. See ##
69ce078b
PE
757## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
758## ------------------------------------------------------------------------- ##
759
760AT_SETUP([No users destructors if stack 0 deleted])
761
762AT_DATA_GRAMMAR([glr-regr9.y],
763[[
764%{
affac613
AD
765# include <stdio.h>
766# include <stdlib.h>
69ce078b
PE
767 static void yyerror (char const *);
768 static int yylex (void);
affac613 769# define YYSTACKEXPANDABLE 0
69ce078b
PE
770 static int tokens = 0;
771 static int destructors = 0;
affac613 772# define USE(Var)
69ce078b
PE
773%}
774
775%glr-parser
776%union { int dummy; }
777%type <dummy> 'a'
778
779%destructor {
780 destructors += 1;
781} 'a'
782
783%%
784
785start:
affac613 786 ambig0 'a' { destructors += 2; USE ($2); }
69ce078b
PE
787 | ambig1 start { destructors += 1; }
788 | ambig2 start { destructors += 1; }
789 ;
790
791ambig0: 'a' ;
792ambig1: 'a' ;
793ambig2: 'a' ;
794
795%%
796
797static int
798yylex (void)
799{
800 tokens += 1;
801 return 'a';
802}
803
804static void
805yyerror (char const *msg)
806{
807 fprintf (stderr, "%s\n", msg);
808}
809
810int
811main (void)
812{
813 int exit_status;
814 exit_status = yyparse ();
815 if (tokens != destructors)
816 {
817 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
818 return 1;
819 }
820 return !exit_status;
821}
822]])
823
824AT_CHECK([[bison -o glr-regr9.c glr-regr9.y]], 0, [],
825[glr-regr9.y: conflicts: 1 reduce/reduce
826])
827AT_COMPILE([glr-regr9])
828
829AT_CHECK([[./glr-regr9]], 0, [],
830[memory exhausted
831])
832
833AT_CLEANUP
d659304d
JD
834
835
836## ------------------------------------------------------------------------- ##
837## Corrupted semantic options if user action cuts parse. ##
838## ------------------------------------------------------------------------- ##
839
bf70fa87 840AT_SETUP([Corrupted semantic options if user action cuts parse])
d659304d
JD
841
842AT_DATA_GRAMMAR([glr-regr10.y],
843[[
844%{
cf806753 845# include <stdlib.h>
d659304d
JD
846# include <stdio.h>
847 static void yyerror (char const *);
848 static int yylex (void);
849 #define GARBAGE_SIZE 50
850 static char garbage[GARBAGE_SIZE];
851%}
852
853%glr-parser
854%union { char *ptr; }
855%type <ptr> start
856
857%%
858
859start:
860 %dprec 2 { $$ = garbage; YYACCEPT; }
861 | %dprec 1 { $$ = garbage; YYACCEPT; }
862 ;
863
864%%
865
866static void
867yyerror (char const *msg)
868{
869 fprintf (stderr, "%s\n", msg);
870}
871
872static int
873yylex (void)
874{
cf806753
PE
875 static int called;
876 if (called++)
877 abort ();
d659304d
JD
878 return 0;
879}
880
881int
882main (void)
883{
c66dfadd
PE
884 int i;
885 for (i = 0; i < GARBAGE_SIZE; i+=1)
886 garbage[i] = 108;
d659304d
JD
887 return yyparse ();
888}
889]])
890
35ee866a 891AT_CHECK([[bison -o glr-regr10.c glr-regr10.y]], 0, [],
d659304d
JD
892[glr-regr10.y: conflicts: 1 reduce/reduce
893])
894AT_COMPILE([glr-regr10])
895
896AT_CHECK([[./glr-regr10]], 0, [], [])
897
898AT_CLEANUP
899
900
901## ------------------------------------------------------------------------- ##
902## Undesirable destructors if user action cuts parse. ##
903## ------------------------------------------------------------------------- ##
904
bf70fa87 905AT_SETUP([Undesirable destructors if user action cuts parse])
d659304d
JD
906
907AT_DATA_GRAMMAR([glr-regr11.y],
908[[
909%{
910# include <stdlib.h>
911 static void yyerror (char const *);
912 static int yylex (void);
913 static int destructors = 0;
914# define USE(val)
915%}
916
917%glr-parser
918%union { int dummy; }
919%type <int> 'a'
920%destructor { destructors += 1; } 'a'
921
922%%
923
924start:
925 'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; }
926 | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; }
927 ;
928
929%%
930
931static void
932yyerror (char const *msg)
933{
934 fprintf (stderr, "%s\n", msg);
935}
936
937static int
938yylex (void)
939{
cf806753
PE
940 static char const input[] = "a";
941 static size_t toknum;
942 if (! (toknum < sizeof input))
943 abort ();
944 return input[toknum++];
d659304d
JD
945}
946
947int
948main (void)
949{
950 int exit_status = yyparse ();
951 if (destructors != 1)
952 {
953 fprintf (stderr, "Destructor calls: %d\n", destructors);
954 return 1;
955 }
956 return exit_status;
957}
958]])
959
35ee866a 960AT_CHECK([[bison -o glr-regr11.c glr-regr11.y]], 0, [],
d659304d
JD
961[glr-regr11.y: conflicts: 1 reduce/reduce
962])
963AT_COMPILE([glr-regr11])
964
965AT_CHECK([[./glr-regr11]], 0, [], [])
966
967AT_CLEANUP
968
969
970## ------------------------------------------------------------------------- ##
520181ab 971## Leaked semantic values if user action cuts parse. ##
d659304d
JD
972## ------------------------------------------------------------------------- ##
973
520181ab 974AT_SETUP([Leaked semantic values if user action cuts parse])
d659304d
JD
975
976AT_DATA_GRAMMAR([glr-regr12.y],
977[[
978%glr-parser
979%union { int dummy; }
520181ab
JD
980%token PARENT_RHS_AFTER
981%type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
982%destructor { parent_rhs_before_value = 0; } parent_rhs_before
983%destructor { merged_value = 0; } merged
984%destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
d659304d
JD
985
986%{
987# include <stdlib.h>
988 static int merge (YYSTYPE, YYSTYPE);
989 static void yyerror (char const *);
990 static int yylex (void);
520181ab
JD
991 static int parent_rhs_before_value = 0;
992 static int merged_value = 0;
993 static int parent_rhs_after_value = 0;
d659304d
JD
994# define USE(val)
995%}
996
997%%
998
999start:
520181ab
JD
1000 alt1 %dprec 1
1001 | alt2 %dprec 2
6d05403d 1002 ;
520181ab
JD
1003
1004alt1:
1005 PARENT_RHS_AFTER {
1006 USE ($1);
1007 parent_rhs_after_value = 0;
1008 }
1009 ;
1010
1011alt2:
1012 parent_rhs_before merged PARENT_RHS_AFTER {
1013 USE (($1, $2, $3));
1014 parent_rhs_before_value = 0;
1015 merged_value = 0;
1016 parent_rhs_after_value = 0;
1017 }
1018 ;
1019
1020parent_rhs_before:
1021 {
1022 USE ($$);
1023 parent_rhs_before_value = 1;
1024 }
1025 ;
1026
1027merged:
1028 %merge<merge> {
1029 USE ($$);
1030 merged_value = 1;
1031 }
1032 | cut %merge<merge> {
1033 USE ($$);
1034 merged_value = 1;
1035 }
d659304d
JD
1036 ;
1037
520181ab
JD
1038cut: { YYACCEPT; } ;
1039
d659304d
JD
1040%%
1041
1042static int
1043merge (YYSTYPE s1, YYSTYPE s2)
1044{
1045 /* Not invoked. */
bf70fa87
JD
1046 char dummy = s1.dummy + s2.dummy;
1047 return dummy;
d659304d
JD
1048}
1049
1050static void
1051yyerror (char const *msg)
1052{
1053 fprintf (stderr, "%s\n", msg);
1054}
1055
1056static int
1057yylex (void)
1058{
520181ab 1059 static int const input[] = { PARENT_RHS_AFTER, 0 };
cf806753
PE
1060 static size_t toknum;
1061 if (! (toknum < sizeof input / sizeof *input))
1062 abort ();
1063 if (input[toknum] == PARENT_RHS_AFTER)
520181ab 1064 parent_rhs_after_value = 1;
cf806753 1065 return input[toknum++];
d659304d
JD
1066}
1067
1068int
1069main (void)
1070{
1071 int exit_status = yyparse ();
520181ab 1072 if (parent_rhs_before_value)
d659304d 1073 {
520181ab
JD
1074 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1075 exit_status = 1;
1076 }
1077 if (merged_value)
1078 {
1079 fprintf (stderr, "`merged' destructor not called.\n");
1080 exit_status = 1;
1081 }
1082 if (parent_rhs_after_value)
1083 {
1084 fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
1085 exit_status = 1;
d659304d
JD
1086 }
1087 return exit_status;
1088}
1089]])
1090
35ee866a 1091AT_CHECK([[bison -o glr-regr12.c glr-regr12.y]], 0, [],
520181ab 1092[glr-regr12.y: conflicts: 1 shift/reduce, 1 reduce/reduce
d659304d
JD
1093])
1094AT_COMPILE([glr-regr12])
1095
1096AT_CHECK([[./glr-regr12]], 0, [], [])
1097
1098AT_CLEANUP
bf70fa87
JD
1099
1100
1101## ------------------------------------------------------------------------- ##
1102## Incorrect lookahead during deterministic GLR. See ##
3f001415
JD
1103## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1104## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
bf70fa87
JD
1105## ------------------------------------------------------------------------- ##
1106
1107AT_SETUP([Incorrect lookahead during deterministic GLR])
1108
1109AT_DATA_GRAMMAR([glr-regr13.y],
1110[[
1111/* Tests:
1112 - Defaulted state with initial yychar: yychar == YYEMPTY.
1113 - Nondefaulted state: yychar != YYEMPTY.
1114 - Defaulted state after lookahead: yychar != YYEMPTY.
3f001415
JD
1115 - Defaulted state after shift: yychar == YYEMPTY.
1116 - User action changing the lookahead. */
bf70fa87
JD
1117
1118%{
1119 #include <stdio.h>
1120 static void yyerror (char const *);
1121 static int yylex (void);
742e4900 1122 static void print_lookahead (char const *);
bf70fa87
JD
1123 #define USE(value)
1124%}
1125
1126%union { char value; }
1127%type <value> 'a' 'b'
1128%glr-parser
1129%locations
1130
1131%%
1132
1133start:
3f001415 1134 defstate_init defstate_shift 'b' change_lookahead 'a' {
bf70fa87 1135 USE ($3);
742e4900 1136 print_lookahead ("start <- defstate_init defstate_shift 'b'");
bf70fa87
JD
1137 }
1138 ;
1139defstate_init:
1140 {
742e4900 1141 print_lookahead ("defstate_init <- empty string");
bf70fa87
JD
1142 }
1143 ;
1144defstate_shift:
1145 nondefstate defstate_look 'a' {
1146 USE ($3);
742e4900 1147 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
bf70fa87
JD
1148 }
1149 ;
1150defstate_look:
1151 {
742e4900 1152 print_lookahead ("defstate_look <- empty string");
bf70fa87
JD
1153 }
1154 ;
1155nondefstate:
1156 {
742e4900 1157 print_lookahead ("nondefstate <- empty string");
bf70fa87
JD
1158 }
1159 | 'b' {
1160 USE ($1);
742e4900 1161 print_lookahead ("nondefstate <- 'b'");
bf70fa87
JD
1162 }
1163 ;
3f001415
JD
1164change_lookahead:
1165 {
1166 yychar = 'a';
1167 }
1168 ;
bf70fa87
JD
1169
1170%%
1171
1172static void
1173yyerror (char const *msg)
1174{
1175 fprintf (stderr, "%s\n", msg);
1176}
1177
1178static int
1179yylex (void)
1180{
cf806753
PE
1181 static char const input[] = "ab";
1182 static size_t toknum;
1183 if (! (toknum < sizeof input))
1184 abort ();
bf70fa87 1185 yylloc.first_line = yylloc.last_line = 1;
cf806753
PE
1186 yylloc.first_column = yylloc.last_column = toknum + 1;
1187 yylval.value = input[toknum] + 'A' - 'a';
1188 return input[toknum++];
bf70fa87
JD
1189}
1190
1191static void
742e4900 1192print_lookahead (char const *reduction)
bf70fa87
JD
1193{
1194 printf ("%s:\n yychar=", reduction);
1195 if (yychar == YYEMPTY)
1196 printf ("YYEMPTY");
1197 else if (yychar == YYEOF)
1198 printf ("YYEOF");
1199 else
1200 {
1201 printf ("'%c', yylval='", yychar);
1202 if (yylval.value > ' ')
1203 printf ("%c", yylval.value);
1204 printf ("', yylloc=(%d,%d),(%d,%d)",
1205 yylloc.first_line, yylloc.first_column,
1206 yylloc.last_line, yylloc.last_column);
1207 }
1208 printf ("\n");
1209}
1210
1211int
1212main (void)
1213{
1214 yychar = '#'; /* Not a token in the grammar. */
1215 yylval.value = '!';
1216 return yyparse ();
1217}
1218]])
1219
35ee866a 1220AT_CHECK([[bison -o glr-regr13.c glr-regr13.y]], 0, [], [])
bf70fa87
JD
1221AT_COMPILE([glr-regr13])
1222
1223AT_CHECK([[./glr-regr13]], 0,
1224[defstate_init <- empty string:
1225 yychar=YYEMPTY
1226nondefstate <- empty string:
1227 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1228defstate_look <- empty string:
1229 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1230defstate_shift <- nondefstate defstate_look 'a':
1231 yychar=YYEMPTY
1232start <- defstate_init defstate_shift 'b':
1233 yychar=YYEMPTY
1234], [])
1235
1236AT_CLEANUP
1237
1238
1239## ------------------------------------------------------------------------- ##
1240## Incorrect lookahead during nondeterministic GLR. ##
1241## ------------------------------------------------------------------------- ##
1242
1243AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1244
1245AT_DATA_GRAMMAR([glr-regr14.y],
1246[[
1247/* Tests:
b7691f15 1248 - Conflicting actions (split-off parse, which copies lookahead need,
bf70fa87
JD
1249 which is necessarily yytrue) and nonconflicting actions (non-split-off
1250 parse) for nondefaulted state: yychar != YYEMPTY.
b7691f15 1251 - Merged deferred actions (lookahead need and RHS from different stack
bf70fa87
JD
1252 than the target state) and nonmerged deferred actions (same stack).
1253 - Defaulted state after lookahead: yychar != YYEMPTY.
1254 - Defaulted state after shift: yychar == YYEMPTY.
b7691f15 1255 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
bf70fa87
JD
1256 seen the lookahead but current stack has not).
1257 - Exceeding stack capacity (stack explosion), and thus reallocating
b7691f15 1258 lookahead need array.
bf70fa87
JD
1259 Note that it does not seem possible to see the initial yychar value during
1260 nondeterministic operation since:
1261 - In order to preserve the initial yychar, only defaulted states may be
1262 entered.
1263 - If only defaulted states are entered, there are no conflicts, so
1264 nondeterministic operation does not start. */
1265
1266%union { char value; }
1267
1268%{
cf806753 1269 #include <stdlib.h>
bf70fa87
JD
1270 #include <stdio.h>
1271 static void yyerror (char const *);
1272 static int yylex (void);
742e4900 1273 static void print_lookahead (char const *);
bf70fa87
JD
1274 static char merge (union YYSTYPE, union YYSTYPE);
1275 #define USE(value)
1276%}
1277
1278%type <value> 'a' 'b' 'c' 'd' stack_explosion
1279%glr-parser
1280%locations
1281
1282%%
1283
1284start:
1285 merge 'c' stack_explosion {
1286 USE ($2); USE ($3);
742e4900 1287 print_lookahead ("start <- merge 'c' stack_explosion");
bf70fa87
JD
1288 }
1289 ;
1290
b7691f15 1291/* When merging the 2 deferred actions, the lookahead needs are different. */
bf70fa87
JD
1292merge:
1293 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1294 USE ($2); USE ($3);
742e4900 1295 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
bf70fa87
JD
1296 }
1297 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1298 USE ($3); USE ($5);
742e4900 1299 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
bf70fa87
JD
1300 " defstate_shift");
1301 }
1302 ;
1303
1304nonconflict1:
1305 {
742e4900 1306 print_lookahead ("nonconflict1 <- empty string");
bf70fa87
JD
1307 }
1308 ;
1309nonconflict2:
1310 {
742e4900 1311 print_lookahead ("nonconflict2 <- empty string");
bf70fa87
JD
1312 }
1313 | 'a' {
1314 USE ($1);
742e4900 1315 print_lookahead ("nonconflict2 <- 'a'");
bf70fa87
JD
1316 }
1317 ;
1318conflict:
1319 {
742e4900 1320 print_lookahead ("conflict <- empty string");
bf70fa87
JD
1321 }
1322 ;
1323defstate_look:
1324 {
742e4900 1325 print_lookahead ("defstate_look <- empty string");
bf70fa87
JD
1326 }
1327 ;
1328
b7691f15 1329/* yychar != YYEMPTY but lookahead need is yyfalse. */
bf70fa87
JD
1330defstate_shift:
1331 {
742e4900 1332 print_lookahead ("defstate_shift <- empty string");
bf70fa87
JD
1333 }
1334 ;
1335
1336stack_explosion:
1337 { $$ = '\0'; }
1338 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1339 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1340 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1341 ;
1342alt1:
1343 'd' no_look {
1344 USE ($1);
1345 if (yychar != 'd' && yychar != YYEOF)
1346 {
1347 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1348 }
1349 }
1350 ;
1351alt2:
1352 'd' no_look {
1353 USE ($1);
1354 if (yychar != 'd' && yychar != YYEOF)
1355 {
1356 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1357 }
1358 }
1359 ;
1360alt3:
1361 'd' no_look {
1362 USE ($1);
1363 if (yychar != 'd' && yychar != YYEOF)
1364 {
1365 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1366 }
1367 }
1368 ;
1369no_look:
1370 {
1371 if (yychar != YYEMPTY)
1372 {
1373 fprintf (stderr,
1374 "Found lookahead where shouldn't during stack explosion.\n");
1375 }
1376 }
1377 ;
1378
1379%%
1380
1381static void
1382yyerror (char const *msg)
1383{
1384 fprintf (stderr, "%s\n", msg);
1385}
1386
1387static int
1388yylex (void)
1389{
cf806753
PE
1390 static char const input[] = "abcdddd";
1391 static size_t toknum;
1392 if (! (toknum < sizeof input))
1393 abort ();
bf70fa87 1394 yylloc.first_line = yylloc.last_line = 1;
cf806753
PE
1395 yylloc.first_column = yylloc.last_column = toknum + 1;
1396 yylval.value = input[toknum] + 'A' - 'a';
1397 return input[toknum++];
bf70fa87
JD
1398}
1399
1400static void
742e4900 1401print_lookahead (char const *reduction)
bf70fa87
JD
1402{
1403 printf ("%s:\n yychar=", reduction);
1404 if (yychar == YYEMPTY)
1405 printf ("YYEMPTY");
1406 else if (yychar == YYEOF)
1407 printf ("YYEOF");
1408 else
1409 {
1410 printf ("'%c', yylval='", yychar);
1411 if (yylval.value > ' ')
1412 printf ("%c", yylval.value);
1413 printf ("', yylloc=(%d,%d),(%d,%d)",
1414 yylloc.first_line, yylloc.first_column,
1415 yylloc.last_line, yylloc.last_column);
1416 }
1417 printf ("\n");
1418}
1419
1420static char
1421merge (union YYSTYPE s1, union YYSTYPE s2)
1422{
1423 char dummy = s1.value + s2.value;
1424 return dummy;
1425}
1426
1427int
1428main (void)
1429{
1430 yychar = '#'; /* Not a token in the grammar. */
1431 yylval.value = '!';
1432 return yyparse ();
1433}
1434]])
1435
35ee866a 1436AT_CHECK([[bison -o glr-regr14.c glr-regr14.y]], 0, [],
bf70fa87
JD
1437[glr-regr14.y: conflicts: 3 reduce/reduce
1438])
1439AT_COMPILE([glr-regr14])
1440
1441AT_CHECK([[./glr-regr14]], 0,
1442[conflict <- empty string:
1443 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1444defstate_look <- empty string:
1445 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1446nonconflict2 <- empty string:
1447 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1448defstate_shift <- empty string:
1449 yychar=YYEMPTY
1450merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1451 yychar=YYEMPTY
1452start <- merge 'c' stack_explosion:
1453 yychar=YYEOF
1454], [])
1455
1456AT_CLEANUP
35ee866a
JD
1457
1458
1459## ------------------------------------------------------------------------- ##
1460## Leaked semantic values when reporting ambiguity. ##
1461## ------------------------------------------------------------------------- ##
1462
1463AT_SETUP([Leaked semantic values when reporting ambiguity])
1464
1465AT_DATA_GRAMMAR([glr-regr15.y],
1466[[
1467%glr-parser
35ee866a
JD
1468%destructor { parent_rhs_before_value = 0; } parent_rhs_before
1469
1470%{
1471# include <stdlib.h>
1472 static void yyerror (char const *);
1473 static int yylex (void);
1474 static int parent_rhs_before_value = 0;
1475# define USE(val)
1476%}
1477
1478%%
1479
1480start:
1481 alt1 %dprec 1
1482 | alt2 %dprec 2
1483 ;
1484
1485/* This stack must be merged into the other stacks *last* (added at the
1486 beginning of the semantic options list) so that yyparse will choose to clean
1487 it up rather than the tree for which some semantic actions have been
1488 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1489 those other trees are not cleaned up. */
1490alt1: ;
1491
1492alt2:
1493 parent_rhs_before ambiguity {
1494 USE ($1);
1495 parent_rhs_before_value = 0;
1496 }
1497 ;
1498
1499parent_rhs_before:
1500 {
1501 USE ($$);
1502 parent_rhs_before_value = 1;
1503 }
1504 ;
1505
1506ambiguity: ambiguity1 | ambiguity2 ;
1507ambiguity1: ;
1508ambiguity2: ;
1509
1510%%
1511
1512static void
1513yyerror (char const *msg)
1514{
1515 fprintf (stderr, "%s\n", msg);
1516}
1517
1518static int
1519yylex (void)
1520{
cf806753
PE
1521 static int called;
1522 if (called++)
1523 abort ();
35ee866a
JD
1524 return 0;
1525}
1526
1527int
1528main (void)
1529{
1530 int exit_status = yyparse () != 1;
1531 if (parent_rhs_before_value)
1532 {
1533 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1534 exit_status = 1;
1535 }
1536 return exit_status;
1537}
1538]])
1539
1540AT_CHECK([[bison -o glr-regr15.c glr-regr15.y]], 0, [],
1541[glr-regr15.y: conflicts: 2 reduce/reduce
1542])
1543AT_COMPILE([glr-regr15])
1544
1545AT_CHECK([[./glr-regr15]], 0, [],
1546[syntax is ambiguous
1547])
1548
1549AT_CLEANUP
ae952af2
JD
1550
1551
1552## ------------------------------------------------------------------------- ##
1553## Leaked lookahead after nondeterministic parse syntax error. ##
1554## ------------------------------------------------------------------------- ##
1555
1556AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1557AT_DATA_GRAMMAR([glr-regr16.y],
1558[[
1559%glr-parser
1560%destructor { lookahead_value = 0; } 'b'
1561
1562%{
1563# include <stdlib.h>
1564 static void yyerror (char const *);
1565 static int yylex (void);
1566 static int lookahead_value = 0;
1567# define USE(val)
1568%}
1569
1570%%
1571
1572start: alt1 'a' | alt2 'a' ;
1573alt1: ;
1574alt2: ;
1575
1576%%
1577
1578static void
1579yyerror (char const *msg)
1580{
1581 fprintf (stderr, "%s\n", msg);
1582}
1583
1584static int
1585yylex (void)
1586{
cf806753
PE
1587 static char const input[] = "ab";
1588 static size_t toknum;
1589 if (! (toknum < sizeof input))
1590 abort ();
1591 if (input[toknum] == 'b')
ae952af2 1592 lookahead_value = 1;
cf806753 1593 return input[toknum++];
ae952af2
JD
1594}
1595
1596int
1597main (void)
1598{
1599 int exit_status = yyparse () != 1;
1600 if (lookahead_value)
1601 {
1602 fprintf (stderr, "Lookahead destructor not called.\n");
1603 exit_status = 1;
1604 }
1605 return exit_status;
1606}
1607]])
1608
1609AT_CHECK([[bison -o glr-regr16.c glr-regr16.y]], 0, [],
1610[glr-regr16.y: conflicts: 1 reduce/reduce
1611])
1612AT_COMPILE([glr-regr16])
1613
1614AT_CHECK([[./glr-regr16]], 0, [],
1615[syntax error
1616])
1617
1618AT_CLEANUP
8710fc41
JD
1619
1620
1621## ------------------------------------------------------------------------- ##
1622## Uninitialized location when reporting ambiguity. ##
1623## ------------------------------------------------------------------------- ##
1624
1625AT_SETUP([Uninitialized location when reporting ambiguity])
1626AT_DATA_GRAMMAR([glr-regr17.y],
1627[[
1628%glr-parser
1629%locations
1630%pure-parser
1631%error-verbose
1632
1633%union { int dummy; }
1634
1635%{
1636 static void yyerror (YYLTYPE *, char const *);
1637 static int yylex (YYSTYPE *, YYLTYPE *);
1638%}
1639
1640%initial-action {
1641 @$.first_line = 1;
1642 @$.first_column = 1;
1643 @$.last_line = 1;
1644 @$.last_column = 1;
1645}
1646
1647%%
1648
5ad0a449
JD
1649/* Tests the case of an empty RHS that has inherited the location of the
1650 previous nonterminal, which is unresolved. That location is reported as the
1651 last position of the ambiguity. */
1652start: ambig1 empty1 | ambig2 empty2 ;
1653
8710fc41 1654/* Tests multiple levels of yyresolveLocations recursion. */
8710fc41
JD
1655ambig1: sub_ambig1 | sub_ambig2 ;
1656ambig2: sub_ambig1 | sub_ambig2 ;
1657
5ad0a449
JD
1658/* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1659 has inherited the initial location. The empty RHS's location is reported as
1660 the first position in the ambiguity. */
1661sub_ambig1: empty1 'a' 'b' ;
1662sub_ambig2: empty2 'a' 'b' ;
1663empty1: ;
1664empty2: ;
8710fc41
JD
1665
1666%%
1667
1668static void
1669yyerror (YYLTYPE *locp, char const *msg)
1670{
1671 fprintf (stderr, "Error at %d.%d-%d.%d: %s.\n", locp->first_line,
1672 locp->first_column, locp->last_line, locp->last_column, msg);
1673}
1674
6d05403d 1675static int
8710fc41
JD
1676yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1677{
6d05403d 1678 static char const input[] = "ab";
cf806753
PE
1679 static size_t toknum;
1680 if (! (toknum < sizeof input))
1681 abort ();
6d05403d 1682 lvalp->dummy = 0;
8710fc41 1683 llocp->first_line = llocp->last_line = 2;
cf806753 1684 llocp->first_column = toknum + 1;
8710fc41 1685 llocp->last_column = llocp->first_column + 1;
cf806753 1686 return input[toknum++];
8710fc41
JD
1687}
1688
1689int
1690main (void)
1691{
1692 return yyparse () != 1;
1693}
1694]])
1695
1696AT_CHECK([[bison -o glr-regr17.c glr-regr17.y]], 0, [],
1697[glr-regr17.y: conflicts: 3 reduce/reduce
1698])
1699AT_COMPILE([glr-regr17])
1700
1701AT_CHECK([[./glr-regr17]], 0, [],
1702[Error at 1.1-2.3: syntax is ambiguous.
1703])
1704
1705AT_CLEANUP
8ee5b538
JD
1706
1707
1708## -------------------------------------------------------------##
1709## Missed %merge type warnings when LHS type is declared later. ##
1710## -------------------------------------------------------------##
1711
1712AT_SETUP([Missed %merge type warnings when LHS type is declared later])
1713AT_DATA_GRAMMAR([glr-regr18.y],
1714[[%glr-parser
1715
1716%{
cf806753 1717 #include <stdlib.h>
8ee5b538
JD
1718 static void yyerror (char const *);
1719 static int yylex ();
1720%}
1721
1722%union {
1723 int type1;
1724 int type2;
dd60572a 1725 int type3;
8ee5b538
JD
1726}
1727
1728%%
1729
1730sym1: sym2 %merge<merge> { $$ = $1; } ;
dd60572a
JD
1731sym2: sym3 %merge<merge> { $$ = $1; } ;
1732sym3: %merge<merge> { $$ = 0; } ;
8ee5b538
JD
1733
1734%type <type1> sym1;
1735%type <type2> sym2;
dd60572a 1736%type <type3> sym3;
8ee5b538
JD
1737
1738%%
1739
1740static void
1741yyerror (char const *msg)
1742{
1743 fprintf (stderr, "%s\n", msg);
1744}
1745
1746static int
1747yylex ()
1748{
cf806753
PE
1749 static int called;
1750 if (called++)
1751 abort ();
8ee5b538
JD
1752 return 0;
1753}
1754
1755int
1756main (void)
1757{
1758 return yyparse ();
1759}
1760]])
1761
3b452f4e 1762AT_CHECK([[bison -o glr-regr18.c glr-regr18.y]], 1, [],
231ed89a
PE
1763[glr-regr18.y:26.18-24: result type clash on merge function `merge': <type2> != <type1>
1764glr-regr18.y:25.18-24: previous declaration
1765glr-regr18.y:27.13-19: result type clash on merge function `merge': <type3> != <type2>
1766glr-regr18.y:26.18-24: previous declaration
8ee5b538
JD
1767])
1768
1769AT_CLEANUP