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