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