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