]> git.saurik.com Git - bison.git/blame - tests/glr-regression.at
maint: use *.texi.
[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>
77519a7d 35#include <assert.h>
ede3d3bc
PH
36
37#define YYSTYPE int
38static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1);
55f48c48 39]AT_YYERROR_DECLARE[
290a8ff2 40]AT_YYLEX_DECLARE[
ede3d3bc
PH
41%}
42
43
44%glr-parser
45
46
47/* -------- productions ------ */
48%%
49
50StartSymbol: E { $$=0; } %merge <exprMerge>
51 ;
52
53E: E 'P' E { $$=1; printf("E -> E 'P' E\n"); } %merge <exprMerge>
54 | 'B' { $$=2; printf("E -> 'B'\n"); } %merge <exprMerge>
55 ;
56
57
58
59/* ---------- C code ----------- */
60%%
61
62static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1)
63{
64 (void) x0;
65 (void) x1;
66 printf ("<OR>\n");
67 return 0;
68}
69
70int
71main (void)
72{
73 return yyparse ();
74}
75
55f48c48 76]AT_YYERROR_DEFINE[
ede3d3bc
PH
77
78int
79yylex (void)
80{
81 for (;;)
82 {
cf806753 83 int ch;
77519a7d 84 assert (!feof (stdin));
cf806753 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>
77519a7d 131 #include <assert.h>
55f48c48 132 ]AT_YYERROR_DECLARE[
290a8ff2 133 ]AT_YYLEX_DECLARE[
ede3d3bc
PH
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%%
55f48c48 173]AT_YYERROR_DEFINE[
cf806753 174FILE *input;
ede3d3bc
PH
175
176int
177yylex (void)
d6d67dbd 178{
ede3d3bc 179 char buf[50];
c70fdfcd 180 char *s;
77519a7d 181 assert (!feof (stdin));
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;
77519a7d 193 assert (strlen (buf) < sizeof buf - 1);
c70fdfcd
PE
194 s = (char *) malloc (strlen (buf) + 1);
195 strcpy (s, buf);
196 yylval = s;
ede3d3bc
PH
197 return 'V';
198}
199
ede3d3bc
PH
200int
201main (int argc, char **argv)
d6d67dbd 202{
a9739e7c
PE
203 input = stdin;
204 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
ede3d3bc
PH
205 return yyparse ();
206}
207]])
55f48c48 208AT_BISON_OPTION_POPDEFS
ede3d3bc 209
da730230 210AT_BISON_CHECK([[-o glr-regr2a.c glr-regr2a.y]], 0, [],
ede3d3bc
PH
211[glr-regr2a.y: conflicts: 2 shift/reduce
212])
213AT_COMPILE([glr-regr2a])
214
7d2d521f 215AT_PARSER_CHECK([[echo s VARIABLE_1 t v x q | ./glr-regr2a]], 0,
ede3d3bc
PH
216[[Variable: 'VARIABLE_1'
217]], [])
7d2d521f
JD
218AT_PARSER_CHECK([[echo s VARIABLE_1 , ANOTHER_VARIABLE_2 t e | ./glr-regr2a]],
2190,
ede3d3bc
PH
220[[Varlist: 'VARIABLE_1,ANOTHER_VARIABLE_2'
221]])
7d2d521f 222AT_PARSER_CHECK([[echo s VARIABLE_3 t v x | ./glr-regr2a]], 0,
ede3d3bc
PH
223[[Variable: 'VARIABLE_3'
224]], [])
225
226
5e6f62f2
PH
227AT_CLEANUP
228
229## ------------------------------------------------------------ ##
230## Improper merging of GLR delayed action sets ##
231## ------------------------------------------------------------ ##
232
233AT_SETUP([Improper merging of GLR delayed action sets])
234
55f48c48 235AT_BISON_OPTION_PUSHDEFS
5e6f62f2
PH
236AT_DATA_GRAMMAR([glr-regr3.y],
237[[/* Regression Test: Improper merging of GLR delayed action sets. */
238/* Reported by M. Rosien */
239
240%{
241#include <stdio.h>
cf806753 242#include <stdlib.h>
5e6f62f2 243#include <stdarg.h>
77519a7d 244#include <assert.h>
5e6f62f2
PH
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];
77519a7d 305 assert (!feof (stdin));
a9739e7c 306 if (fscanf (input, "%2s", inp) == EOF)
5e6f62f2 307 return 0;
1beb0b24 308 switch (inp[0])
5e6f62f2
PH
309 {
310 case 'p': return P[inp[1] - '1'];
311 case 't': return T[inp[1] - '1'];
312 case 'o': return O[inp[1] - '1'];
313 }
314 return BAD_CHAR;
315}
316
55f48c48
AD
317int
318main(int argc, char* argv[])
319{
a9739e7c
PE
320 input = stdin;
321 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
5e6f62f2
PH
322 return yyparse ();
323}
324]])
55f48c48 325AT_BISON_OPTION_POPDEFS
5e6f62f2 326
da730230 327AT_BISON_CHECK([[-o glr-regr3.c glr-regr3.y]], 0, [],
5e6f62f2
PH
328[glr-regr3.y: conflicts: 1 shift/reduce, 1 reduce/reduce
329])
330AT_COMPILE([glr-regr3])
331
7d2d521f
JD
332AT_PARSER_CHECK([[echo p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2 | ./glr-regr3]],
3330,
5e6f62f2
PH
334[[Result: 1c04
335]], [])
336
ede3d3bc 337AT_CLEANUP
f9315de5
PE
338
339
4158e0a1
JD
340## ------------------------------------------------------------------------- ##
341## Duplicate representation of merged trees. See ##
342## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>. ##
343## ------------------------------------------------------------------------- ##
f9315de5
PE
344
345AT_SETUP([Duplicate representation of merged trees])
346
55f48c48 347AT_BISON_OPTION_PUSHDEFS
f9315de5 348AT_DATA_GRAMMAR([glr-regr4.y],
1bd0deda
PE
349[[
350%union { char *ptr; }
f9315de5
PE
351%type <ptr> S A A1 A2 B
352%glr-parser
353
354%{
355 #include <stdio.h>
356 #include <stdlib.h>
357 #include <string.h>
358 static char *merge (YYSTYPE, YYSTYPE);
1bd0deda 359 static char *make_value (char const *, char const *);
55f48c48
AD
360 ]AT_YYERROR_DECLARE[
361 ]AT_YYLEX_DECLARE[
7d2d521f
JD
362 static char *ptrs[100];
363 static char **ptrs_next = ptrs;
f9315de5
PE
364%}
365
366%%
367
368tree: S { printf ("%s\n", $1); } ;
369
370S:
371 A %merge<merge> { $$ = make_value ("S", $1); }
372 | B %merge<merge> { $$ = make_value ("S", $1); }
373 ;
374
375A:
376 A1 %merge<merge> { $$ = make_value ("A", $1); }
377 | A2 %merge<merge> { $$ = make_value ("A", $1); }
378 ;
379
380A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
381A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
382B: 'a' { $$ = make_value ("B", "'a'"); } ;
383
384%%
55f48c48
AD
385]AT_YYERROR_DEFINE[
386]AT_YYLEX_DEFINE([a])[
f9315de5
PE
387
388int
389main (void)
390{
7d2d521f
JD
391 int status = yyparse ();
392 while (ptrs_next != ptrs)
393 free (*--ptrs_next);
394 return status;
f9315de5
PE
395}
396
397static char *
1bd0deda 398make_value (char const *parent, char const *child)
f9315de5
PE
399{
400 char const format[] = "%s <- %s";
7d2d521f 401 char *value = *ptrs_next++ =
7812f299 402 (char *) malloc (strlen (parent) + strlen (child) + sizeof format);
f9315de5
PE
403 sprintf (value, format, parent, child);
404 return value;
405}
406
407static char *
408merge (YYSTYPE s1, YYSTYPE s2)
409{
410 char const format[] = "merge{ %s and %s }";
7d2d521f 411 char *value = *ptrs_next++ =
7812f299 412 (char *) malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format);
f9315de5
PE
413 sprintf (value, format, s1.ptr, s2.ptr);
414 return value;
415}
f9315de5 416]])
55f48c48 417AT_BISON_OPTION_POPDEFS
f9315de5 418
da730230 419AT_BISON_CHECK([[-o glr-regr4.c glr-regr4.y]], 0, [],
f9315de5
PE
420[glr-regr4.y: conflicts: 1 reduce/reduce
421])
422AT_COMPILE([glr-regr4])
423
7d2d521f 424AT_PARSER_CHECK([[./glr-regr4]], 0,
f9315de5
PE
425[[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
426]], [])
427
428AT_CLEANUP
adc90f13
PE
429
430
4158e0a1
JD
431## -------------------------------------------------------------------------- ##
432## User destructor for unresolved GLR semantic value. See ##
433## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>. ##
434## -------------------------------------------------------------------------- ##
adc90f13
PE
435
436AT_SETUP([User destructor for unresolved GLR semantic value])
437
55f48c48 438AT_BISON_OPTION_PUSHDEFS
adc90f13 439AT_DATA_GRAMMAR([glr-regr5.y],
1bd0deda
PE
440[[
441%{
adc90f13
PE
442 #include <stdio.h>
443 #include <stdlib.h>
55f48c48
AD
444 ]AT_YYERROR_DECLARE[
445 ]AT_YYLEX_DECLARE[
adc90f13
PE
446 enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
447%}
448
449%glr-parser
450%union { int value; }
451%type <value> start
452
453%destructor {
454 if ($$ != MAGIC_VALUE)
455 {
456 fprintf (stderr, "Bad destructor call.\n");
457 exit (EXIT_FAILURE);
458 }
459} start
460
461%%
462
463start:
464 'a' { $$ = MAGIC_VALUE; }
465 | 'a' { $$ = MAGIC_VALUE; }
466 ;
467
468%%
55f48c48
AD
469]AT_YYLEX_DEFINE(a)[
470]AT_YYERROR_DEFINE[
adc90f13
PE
471int
472main (void)
473{
474 return yyparse () != 1;
475}
476]])
55f48c48 477AT_BISON_OPTION_POPDEFS
adc90f13 478
da730230 479AT_BISON_CHECK([[-o glr-regr5.c glr-regr5.y]], 0, [],
adc90f13
PE
480[glr-regr5.y: conflicts: 1 reduce/reduce
481])
482AT_COMPILE([glr-regr5])
483
7d2d521f 484AT_PARSER_CHECK([[./glr-regr5]], 0, [],
42a6501d
PE
485[syntax is ambiguous
486])
487
488AT_CLEANUP
489
490
4158e0a1
JD
491## -------------------------------------------------------------------------- ##
492## User destructor after an error during a split parse. See ##
493## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>. ##
494## -------------------------------------------------------------------------- ##
42a6501d
PE
495
496AT_SETUP([User destructor after an error during a split parse])
497
55f48c48 498AT_BISON_OPTION_PUSHDEFS
42a6501d 499AT_DATA_GRAMMAR([glr-regr6.y],
1bd0deda
PE
500[[
501%{
42a6501d
PE
502 #include <stdio.h>
503 #include <stdlib.h>
55f48c48
AD
504 ]AT_YYERROR_DECLARE[
505 ]AT_YYLEX_DECLARE[
42a6501d
PE
506%}
507
508%glr-parser
509%union { int value; }
510%type <value> 'a'
511
512%destructor {
513 printf ("Destructor called.\n");
514} 'a'
515
516%%
517
518start: 'a' | 'a' ;
519
520%%
55f48c48 521]AT_YYERROR_DEFINE[
290a8ff2 522]AT_YYLEX_DEFINE(a)[
42a6501d
PE
523int
524main (void)
525{
526 return yyparse () != 1;
527}
528]])
55f48c48 529AT_BISON_OPTION_POPDEFS
42a6501d 530
da730230 531AT_BISON_CHECK([[-o glr-regr6.c glr-regr6.y]], 0, [],
42a6501d
PE
532[glr-regr6.y: conflicts: 1 reduce/reduce
533])
534AT_COMPILE([glr-regr6])
535
7d2d521f 536AT_PARSER_CHECK([[./glr-regr6]], 0,
42a6501d
PE
537[Destructor called.
538],
adc90f13
PE
539[syntax is ambiguous
540])
541
542AT_CLEANUP
1bd0deda
PE
543
544
545## ------------------------------------------------------------------------- ##
4158e0a1 546## Duplicated user destructor for lookahead. See ##
1bd0deda
PE
547## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>. ##
548## ------------------------------------------------------------------------- ##
549
550AT_SETUP([Duplicated user destructor for lookahead])
551
55f48c48 552AT_BISON_OPTION_PUSHDEFS
1bd0deda
PE
553AT_DATA_GRAMMAR([glr-regr7.y],
554[[
555%{
556 #include <stdio.h>
557 #include <stdlib.h>
55f48c48
AD
558 ]AT_YYERROR_DECLARE[
559 ]AT_YYLEX_DECLARE[
1bd0deda 560 #define YYSTACKEXPANDABLE 0
7d2d521f
JD
561 typedef struct count_node {
562 int count;
563 struct count_node *prev;
564 } count_node;
565 static count_node *tail;
1bd0deda
PE
566%}
567
568%glr-parser
7d2d521f
JD
569%union { count_node *node; }
570%type <node> 'a'
1bd0deda
PE
571
572%destructor {
7d2d521f 573 if ($$->count++)
1bd0deda
PE
574 fprintf (stderr, "Destructor called on same value twice.\n");
575} 'a'
576
577%%
578
579start:
580 stack1 start
581 | stack2 start
582 | /* empty */
583 ;
584stack1: 'a' ;
585stack2: 'a' ;
586
587%%
588
589static int
590yylex (void)
591{
7d2d521f
JD
592 yylval.node = (count_node*) malloc (sizeof *yylval.node);
593 if (!yylval.node)
1bd0deda
PE
594 {
595 fprintf (stderr, "Test inconclusive.\n");
596 exit (EXIT_FAILURE);
597 }
7d2d521f
JD
598 yylval.node->count = 0;
599 yylval.node->prev = tail;
600 tail = yylval.node;
1bd0deda
PE
601 return 'a';
602}
603
55f48c48 604]AT_YYERROR_DEFINE[
1bd0deda
PE
605int
606main (void)
607{
7d2d521f
JD
608 int status = yyparse ();
609 while (tail)
610 {
611 count_node *prev = tail->prev;
612 free (tail);
613 tail = prev;
614 }
615 return status;
1bd0deda
PE
616}
617]])
55f48c48 618AT_BISON_OPTION_POPDEFS
1bd0deda 619
da730230 620AT_BISON_CHECK([[-o glr-regr7.c glr-regr7.y]], 0, [],
1bd0deda
PE
621[glr-regr7.y: conflicts: 2 reduce/reduce
622])
623AT_COMPILE([glr-regr7])
624
7d2d521f 625AT_PARSER_CHECK([[./glr-regr7]], 2, [],
1bd0deda
PE
626[memory exhausted
627])
628
629AT_CLEANUP
44e7ead1
PH
630
631
632## ------------------------------------------------------------------------- ##
633## Incorrect default location for empty right-hand sides. Adapted from bug ##
634## report by Claudia Hermann. ##
635## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
636## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html ##
637## ------------------------------------------------------------------------- ##
638
639AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
640
55f48c48 641AT_BISON_OPTION_PUSHDEFS
44e7ead1
PH
642AT_DATA_GRAMMAR([glr-regr8.y],
643[[
644%{
645 #include <stdio.h>
646 #include <stdlib.h>
55f48c48
AD
647 ]AT_YYERROR_DECLARE[
648 ]AT_YYLEX_DECLARE[
44e7ead1
PH
649%}
650
651%token T_CONSTANT
652%token T_PORT
653%token T_SIGNAL
654
655%glr-parser
656
657%%
658
659
660PortClause : T_PORT InterfaceDeclaration T_PORT
69ce078b
PE
661 { printf("%d/%d - %d/%d - %d/%d\n",
662 @1.first_column, @1.last_column,
663 @2.first_column, @2.last_column,
44e7ead1
PH
664 @3.first_column, @3.last_column); }
665 ;
666
667InterfaceDeclaration : OptConstantWord %dprec 1
668 | OptSignalWord %dprec 2
669 ;
670
671OptConstantWord : /* empty */
672 | T_CONSTANT
673 ;
674
675OptSignalWord : /* empty */
676 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
677 | T_SIGNAL
678 ;
679
680%%
681
55f48c48 682]AT_YYERROR_DEFINE[
44e7ead1
PH
683static int lexIndex;
684
69ce078b 685int yylex (void)
44e7ead1
PH
686{
687 lexIndex += 1;
688 switch (lexIndex)
689 {
cf806753
PE
690 default:
691 abort ();
44e7ead1
PH
692 case 1:
693 yylloc.first_column = 1;
694 yylloc.last_column = 9;
695 return T_PORT;
696 case 2:
697 yylloc.first_column = 13;
698 yylloc.last_column = 17;
699 return T_PORT;
cf806753 700 case 3:
44e7ead1
PH
701 return 0;
702 }
703}
704
705int
69ce078b 706main (void)
44e7ead1
PH
707{
708 yyparse();
709 return 0;
710}
711]])
55f48c48 712AT_BISON_OPTION_POPDEFS
44e7ead1 713
da730230 714AT_BISON_CHECK([[-o glr-regr8.c glr-regr8.y]], 0, [],
44e7ead1
PH
715[glr-regr8.y: conflicts: 1 reduce/reduce
716])
717AT_COMPILE([glr-regr8])
718
7d2d521f 719AT_PARSER_CHECK([[./glr-regr8]], 0,
44e7ead1
PH
720[empty: 9/9
7211/9 - 9/9 - 13/17
722],
723[])
724
725AT_CLEANUP
69ce078b
PE
726
727
728## ------------------------------------------------------------------------- ##
4158e0a1 729## No users destructors if stack 0 deleted. See ##
69ce078b
PE
730## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
731## ------------------------------------------------------------------------- ##
732
733AT_SETUP([No users destructors if stack 0 deleted])
734
55f48c48 735AT_BISON_OPTION_PUSHDEFS
69ce078b
PE
736AT_DATA_GRAMMAR([glr-regr9.y],
737[[
738%{
affac613
AD
739# include <stdio.h>
740# include <stdlib.h>
55f48c48
AD
741 ]AT_YYERROR_DECLARE[
742 ]AT_YYLEX_DECLARE[
affac613 743# define YYSTACKEXPANDABLE 0
69ce078b
PE
744 static int tokens = 0;
745 static int destructors = 0;
affac613 746# define USE(Var)
69ce078b
PE
747%}
748
749%glr-parser
750%union { int dummy; }
751%type <dummy> 'a'
752
753%destructor {
754 destructors += 1;
755} 'a'
756
757%%
758
759start:
affac613 760 ambig0 'a' { destructors += 2; USE ($2); }
69ce078b
PE
761 | ambig1 start { destructors += 1; }
762 | ambig2 start { destructors += 1; }
763 ;
764
765ambig0: 'a' ;
766ambig1: 'a' ;
767ambig2: 'a' ;
768
769%%
770
771static int
772yylex (void)
773{
774 tokens += 1;
775 return 'a';
776}
777
55f48c48 778]AT_YYERROR_DEFINE[
69ce078b
PE
779int
780main (void)
781{
782 int exit_status;
783 exit_status = yyparse ();
784 if (tokens != destructors)
785 {
786 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
787 return 1;
788 }
789 return !exit_status;
790}
791]])
55f48c48 792AT_BISON_OPTION_POPDEFS
69ce078b 793
da730230 794AT_BISON_CHECK([[-o glr-regr9.c glr-regr9.y]], 0, [],
69ce078b
PE
795[glr-regr9.y: conflicts: 1 reduce/reduce
796])
797AT_COMPILE([glr-regr9])
798
7d2d521f 799AT_PARSER_CHECK([[./glr-regr9]], 0, [],
69ce078b
PE
800[memory exhausted
801])
802
803AT_CLEANUP
d659304d
JD
804
805
806## ------------------------------------------------------------------------- ##
807## Corrupted semantic options if user action cuts parse. ##
808## ------------------------------------------------------------------------- ##
809
bf70fa87 810AT_SETUP([Corrupted semantic options if user action cuts parse])
d659304d 811
55f48c48 812AT_BISON_OPTION_PUSHDEFS
d659304d
JD
813AT_DATA_GRAMMAR([glr-regr10.y],
814[[
815%{
cf806753 816# include <stdlib.h>
d659304d 817# include <stdio.h>
55f48c48
AD
818 ]AT_YYERROR_DECLARE[
819 ]AT_YYLEX_DECLARE[
d659304d
JD
820 #define GARBAGE_SIZE 50
821 static char garbage[GARBAGE_SIZE];
822%}
823
824%glr-parser
825%union { char *ptr; }
826%type <ptr> start
827
828%%
829
830start:
831 %dprec 2 { $$ = garbage; YYACCEPT; }
832 | %dprec 1 { $$ = garbage; YYACCEPT; }
833 ;
834
835%%
55f48c48 836]AT_YYERROR_DEFINE[
290a8ff2 837]AT_YYLEX_DEFINE()[
d659304d
JD
838
839int
840main (void)
841{
c66dfadd
PE
842 int i;
843 for (i = 0; i < GARBAGE_SIZE; i+=1)
844 garbage[i] = 108;
d659304d
JD
845 return yyparse ();
846}
847]])
55f48c48 848AT_BISON_OPTION_POPDEFS
d659304d 849
da730230 850AT_BISON_CHECK([[-o glr-regr10.c glr-regr10.y]], 0, [],
d659304d
JD
851[glr-regr10.y: conflicts: 1 reduce/reduce
852])
853AT_COMPILE([glr-regr10])
854
7d2d521f 855AT_PARSER_CHECK([[./glr-regr10]], 0, [], [])
d659304d
JD
856
857AT_CLEANUP
858
859
860## ------------------------------------------------------------------------- ##
861## Undesirable destructors if user action cuts parse. ##
862## ------------------------------------------------------------------------- ##
863
bf70fa87 864AT_SETUP([Undesirable destructors if user action cuts parse])
d659304d 865
55f48c48 866AT_BISON_OPTION_PUSHDEFS
d659304d
JD
867AT_DATA_GRAMMAR([glr-regr11.y],
868[[
869%{
870# include <stdlib.h>
55f48c48
AD
871 ]AT_YYERROR_DECLARE[
872 ]AT_YYLEX_DECLARE[
d659304d
JD
873 static int destructors = 0;
874# define USE(val)
875%}
876
877%glr-parser
878%union { int dummy; }
879%type <int> 'a'
880%destructor { destructors += 1; } 'a'
881
882%%
883
884start:
885 'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; }
886 | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; }
887 ;
888
889%%
890
55f48c48
AD
891]AT_YYERROR_DEFINE[
892]AT_YYLEX_DEFINE([a])[
d659304d
JD
893
894int
895main (void)
896{
897 int exit_status = yyparse ();
898 if (destructors != 1)
899 {
900 fprintf (stderr, "Destructor calls: %d\n", destructors);
901 return 1;
902 }
903 return exit_status;
904}
905]])
55f48c48 906AT_BISON_OPTION_POPDEFS
d659304d 907
da730230 908AT_BISON_CHECK([[-o glr-regr11.c glr-regr11.y]], 0, [],
d659304d
JD
909[glr-regr11.y: conflicts: 1 reduce/reduce
910])
911AT_COMPILE([glr-regr11])
912
7d2d521f 913AT_PARSER_CHECK([[./glr-regr11]], 0, [], [])
d659304d
JD
914
915AT_CLEANUP
916
917
918## ------------------------------------------------------------------------- ##
520181ab 919## Leaked semantic values if user action cuts parse. ##
d659304d
JD
920## ------------------------------------------------------------------------- ##
921
520181ab 922AT_SETUP([Leaked semantic values if user action cuts parse])
d659304d 923
55f48c48 924AT_BISON_OPTION_PUSHDEFS
d659304d
JD
925AT_DATA_GRAMMAR([glr-regr12.y],
926[[
927%glr-parser
928%union { int dummy; }
520181ab
JD
929%token PARENT_RHS_AFTER
930%type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
931%destructor { parent_rhs_before_value = 0; } parent_rhs_before
932%destructor { merged_value = 0; } merged
933%destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
d659304d
JD
934
935%{
936# include <stdlib.h>
77519a7d 937# include <assert.h>
d659304d 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 1005 static size_t toknum;
77519a7d 1006 assert (toknum < sizeof input / sizeof *input);
cf806753 1007 if (input[toknum] == PARENT_RHS_AFTER)
520181ab 1008 parent_rhs_after_value = 1;
cf806753 1009 return input[toknum++];
d659304d
JD
1010}
1011
1012int
1013main (void)
1014{
1015 int exit_status = yyparse ();
520181ab 1016 if (parent_rhs_before_value)
d659304d 1017 {
520181ab
JD
1018 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1019 exit_status = 1;
1020 }
1021 if (merged_value)
1022 {
1023 fprintf (stderr, "`merged' destructor not called.\n");
1024 exit_status = 1;
1025 }
1026 if (parent_rhs_after_value)
1027 {
1028 fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
1029 exit_status = 1;
d659304d
JD
1030 }
1031 return exit_status;
1032}
1033]])
55f48c48 1034AT_BISON_OPTION_POPDEFS
d659304d 1035
da730230 1036AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [],
520181ab 1037[glr-regr12.y: conflicts: 1 shift/reduce, 1 reduce/reduce
d659304d
JD
1038])
1039AT_COMPILE([glr-regr12])
1040
7d2d521f 1041AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
d659304d
JD
1042
1043AT_CLEANUP
bf70fa87
JD
1044
1045
1046## ------------------------------------------------------------------------- ##
1047## Incorrect lookahead during deterministic GLR. See ##
3f001415
JD
1048## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1049## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
bf70fa87
JD
1050## ------------------------------------------------------------------------- ##
1051
1052AT_SETUP([Incorrect lookahead during deterministic GLR])
1053
55f48c48 1054AT_BISON_OPTION_PUSHDEFS
bf70fa87
JD
1055AT_DATA_GRAMMAR([glr-regr13.y],
1056[[
1057/* Tests:
1058 - Defaulted state with initial yychar: yychar == YYEMPTY.
1059 - Nondefaulted state: yychar != YYEMPTY.
1060 - Defaulted state after lookahead: yychar != YYEMPTY.
3f001415
JD
1061 - Defaulted state after shift: yychar == YYEMPTY.
1062 - User action changing the lookahead. */
bf70fa87
JD
1063
1064%{
1065 #include <stdio.h>
77519a7d 1066 #include <assert.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;
77519a7d 1125 assert (toknum < sizeof input);
bf70fa87 1126 yylloc.first_line = yylloc.last_line = 1;
cf806753
PE
1127 yylloc.first_column = yylloc.last_column = toknum + 1;
1128 yylval.value = input[toknum] + 'A' - 'a';
1129 return input[toknum++];
bf70fa87
JD
1130}
1131
1132static void
742e4900 1133print_lookahead (char const *reduction)
bf70fa87
JD
1134{
1135 printf ("%s:\n yychar=", reduction);
1136 if (yychar == YYEMPTY)
1137 printf ("YYEMPTY");
1138 else if (yychar == YYEOF)
1139 printf ("YYEOF");
1140 else
1141 {
1142 printf ("'%c', yylval='", yychar);
1143 if (yylval.value > ' ')
1144 printf ("%c", yylval.value);
1145 printf ("', yylloc=(%d,%d),(%d,%d)",
1146 yylloc.first_line, yylloc.first_column,
1147 yylloc.last_line, yylloc.last_column);
1148 }
1149 printf ("\n");
1150}
1151
1152int
1153main (void)
1154{
1155 yychar = '#'; /* Not a token in the grammar. */
1156 yylval.value = '!';
1157 return yyparse ();
1158}
1159]])
55f48c48 1160AT_BISON_OPTION_POPDEFS
bf70fa87 1161
da730230 1162AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], [])
bf70fa87
JD
1163AT_COMPILE([glr-regr13])
1164
7d2d521f 1165AT_PARSER_CHECK([[./glr-regr13]], 0,
bf70fa87
JD
1166[defstate_init <- empty string:
1167 yychar=YYEMPTY
1168nondefstate <- empty string:
1169 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1170defstate_look <- empty string:
1171 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1172defstate_shift <- nondefstate defstate_look 'a':
1173 yychar=YYEMPTY
1174start <- defstate_init defstate_shift 'b':
1175 yychar=YYEMPTY
1176], [])
1177
1178AT_CLEANUP
1179
1180
1181## ------------------------------------------------------------------------- ##
1182## Incorrect lookahead during nondeterministic GLR. ##
1183## ------------------------------------------------------------------------- ##
1184
1185AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1186
55f48c48 1187AT_BISON_OPTION_PUSHDEFS
bf70fa87
JD
1188AT_DATA_GRAMMAR([glr-regr14.y],
1189[[
1190/* Tests:
b7691f15 1191 - Conflicting actions (split-off parse, which copies lookahead need,
bf70fa87
JD
1192 which is necessarily yytrue) and nonconflicting actions (non-split-off
1193 parse) for nondefaulted state: yychar != YYEMPTY.
b7691f15 1194 - Merged deferred actions (lookahead need and RHS from different stack
bf70fa87
JD
1195 than the target state) and nonmerged deferred actions (same stack).
1196 - Defaulted state after lookahead: yychar != YYEMPTY.
1197 - Defaulted state after shift: yychar == YYEMPTY.
b7691f15 1198 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
bf70fa87
JD
1199 seen the lookahead but current stack has not).
1200 - Exceeding stack capacity (stack explosion), and thus reallocating
b7691f15 1201 lookahead need array.
bf70fa87
JD
1202 Note that it does not seem possible to see the initial yychar value during
1203 nondeterministic operation since:
1204 - In order to preserve the initial yychar, only defaulted states may be
1205 entered.
1206 - If only defaulted states are entered, there are no conflicts, so
1207 nondeterministic operation does not start. */
1208
1209%union { char value; }
1210
1211%{
cf806753 1212 #include <stdlib.h>
bf70fa87 1213 #include <stdio.h>
77519a7d 1214 #include <assert.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;
77519a7d 1331 assert (toknum < sizeof input);
bf70fa87 1332 yylloc.first_line = yylloc.last_line = 1;
cf806753
PE
1333 yylloc.first_column = yylloc.last_column = toknum + 1;
1334 yylval.value = input[toknum] + 'A' - 'a';
1335 return input[toknum++];
bf70fa87
JD
1336}
1337
1338static void
742e4900 1339print_lookahead (char const *reduction)
bf70fa87
JD
1340{
1341 printf ("%s:\n yychar=", reduction);
1342 if (yychar == YYEMPTY)
1343 printf ("YYEMPTY");
1344 else if (yychar == YYEOF)
1345 printf ("YYEOF");
1346 else
1347 {
1348 printf ("'%c', yylval='", yychar);
1349 if (yylval.value > ' ')
1350 printf ("%c", yylval.value);
1351 printf ("', yylloc=(%d,%d),(%d,%d)",
1352 yylloc.first_line, yylloc.first_column,
1353 yylloc.last_line, yylloc.last_column);
1354 }
1355 printf ("\n");
1356}
1357
1358static char
1359merge (union YYSTYPE s1, union YYSTYPE s2)
1360{
1361 char dummy = s1.value + s2.value;
1362 return dummy;
1363}
1364
1365int
1366main (void)
1367{
1368 yychar = '#'; /* Not a token in the grammar. */
1369 yylval.value = '!';
1370 return yyparse ();
1371}
1372]])
55f48c48 1373AT_BISON_OPTION_POPDEFS
bf70fa87 1374
da730230 1375AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
bf70fa87
JD
1376[glr-regr14.y: conflicts: 3 reduce/reduce
1377])
1378AT_COMPILE([glr-regr14])
1379
7d2d521f 1380AT_PARSER_CHECK([[./glr-regr14]], 0,
bf70fa87
JD
1381[conflict <- empty string:
1382 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1383defstate_look <- empty string:
1384 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1385nonconflict2 <- empty string:
1386 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1387defstate_shift <- empty string:
1388 yychar=YYEMPTY
1389merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1390 yychar=YYEMPTY
1391start <- merge 'c' stack_explosion:
1392 yychar=YYEOF
1393], [])
1394
1395AT_CLEANUP
35ee866a
JD
1396
1397
1398## ------------------------------------------------------------------------- ##
1399## Leaked semantic values when reporting ambiguity. ##
1400## ------------------------------------------------------------------------- ##
1401
1402AT_SETUP([Leaked semantic values when reporting ambiguity])
1403
55f48c48 1404AT_BISON_OPTION_PUSHDEFS
35ee866a
JD
1405AT_DATA_GRAMMAR([glr-regr15.y],
1406[[
1407%glr-parser
35ee866a
JD
1408%destructor { parent_rhs_before_value = 0; } parent_rhs_before
1409
1410%{
1411# include <stdlib.h>
55f48c48
AD
1412 ]AT_YYERROR_DECLARE[
1413 ]AT_YYLEX_DECLARE[
35ee866a
JD
1414 static int parent_rhs_before_value = 0;
1415# define USE(val)
1416%}
1417
1418%%
1419
1420start:
1421 alt1 %dprec 1
1422 | alt2 %dprec 2
1423 ;
1424
1425/* This stack must be merged into the other stacks *last* (added at the
1426 beginning of the semantic options list) so that yyparse will choose to clean
1427 it up rather than the tree for which some semantic actions have been
1428 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1429 those other trees are not cleaned up. */
1430alt1: ;
1431
1432alt2:
1433 parent_rhs_before ambiguity {
1434 USE ($1);
1435 parent_rhs_before_value = 0;
1436 }
1437 ;
1438
1439parent_rhs_before:
1440 {
1441 USE ($$);
1442 parent_rhs_before_value = 1;
1443 }
1444 ;
1445
1446ambiguity: ambiguity1 | ambiguity2 ;
1447ambiguity1: ;
1448ambiguity2: ;
1449
1450%%
55f48c48 1451]AT_YYERROR_DEFINE[
290a8ff2 1452]AT_YYLEX_DEFINE()[
35ee866a
JD
1453
1454int
1455main (void)
1456{
1457 int exit_status = yyparse () != 1;
1458 if (parent_rhs_before_value)
1459 {
1460 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1461 exit_status = 1;
1462 }
1463 return exit_status;
1464}
1465]])
55f48c48 1466AT_BISON_OPTION_POPDEFS
35ee866a 1467
da730230 1468AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
35ee866a
JD
1469[glr-regr15.y: conflicts: 2 reduce/reduce
1470])
1471AT_COMPILE([glr-regr15])
1472
7d2d521f 1473AT_PARSER_CHECK([[./glr-regr15]], 0, [],
35ee866a
JD
1474[syntax is ambiguous
1475])
1476
1477AT_CLEANUP
ae952af2
JD
1478
1479
1480## ------------------------------------------------------------------------- ##
1481## Leaked lookahead after nondeterministic parse syntax error. ##
1482## ------------------------------------------------------------------------- ##
1483
1484AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
55f48c48
AD
1485
1486AT_BISON_OPTION_PUSHDEFS
ae952af2
JD
1487AT_DATA_GRAMMAR([glr-regr16.y],
1488[[
1489%glr-parser
1490%destructor { lookahead_value = 0; } 'b'
1491
1492%{
1493# include <stdlib.h>
77519a7d 1494# include <assert.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;
77519a7d 1515 assert (toknum < sizeof input);
cf806753 1516 if (input[toknum] == 'b')
ae952af2 1517 lookahead_value = 1;
cf806753 1518 return input[toknum++];
ae952af2
JD
1519}
1520
1521int
1522main (void)
1523{
1524 int exit_status = yyparse () != 1;
1525 if (lookahead_value)
1526 {
1527 fprintf (stderr, "Lookahead destructor not called.\n");
1528 exit_status = 1;
1529 }
1530 return exit_status;
1531}
1532]])
55f48c48 1533AT_BISON_OPTION_POPDEFS
ae952af2 1534
da730230 1535AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
ae952af2
JD
1536[glr-regr16.y: conflicts: 1 reduce/reduce
1537])
1538AT_COMPILE([glr-regr16])
1539
7d2d521f 1540AT_PARSER_CHECK([[./glr-regr16]], 0, [],
ae952af2
JD
1541[syntax error
1542])
1543
1544AT_CLEANUP
8710fc41
JD
1545
1546
1547## ------------------------------------------------------------------------- ##
1548## Uninitialized location when reporting ambiguity. ##
1549## ------------------------------------------------------------------------- ##
1550
1551AT_SETUP([Uninitialized location when reporting ambiguity])
55f48c48 1552
8d6c1b5e
AD
1553AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations %define api.pure])
1554
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%{
8d6c1b5e
AD
1565 ]AT_YYERROR_DECLARE[
1566 ]AT_YYLEX_DECLARE[
8710fc41
JD
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%%
77519a7d 1596# include <assert.h>
8710fc41 1597
8d6c1b5e 1598]AT_YYERROR_DEFINE[
6d05403d 1599static int
8710fc41
JD
1600yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1601{
6d05403d 1602 static char const input[] = "ab";
cf806753 1603 static size_t toknum;
77519a7d 1604 assert (toknum < sizeof input);
6d05403d 1605 lvalp->dummy = 0;
8710fc41 1606 llocp->first_line = llocp->last_line = 2;
cf806753 1607 llocp->first_column = toknum + 1;
8710fc41 1608 llocp->last_column = llocp->first_column + 1;
cf806753 1609 return input[toknum++];
8710fc41
JD
1610}
1611
1612int
1613main (void)
1614{
1615 return yyparse () != 1;
1616}
1617]])
55f48c48 1618AT_BISON_OPTION_POPDEFS
8710fc41 1619
da730230 1620AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [],
8710fc41
JD
1621[glr-regr17.y: conflicts: 3 reduce/reduce
1622])
1623AT_COMPILE([glr-regr17])
1624
7d2d521f 1625AT_PARSER_CHECK([[./glr-regr17]], 0, [],
8d6c1b5e 1626[1.1-2.2: syntax is ambiguous
8710fc41
JD
1627])
1628
1629AT_CLEANUP
8ee5b538
JD
1630
1631
1632## -------------------------------------------------------------##
1633## Missed %merge type warnings when LHS type is declared later. ##
1634## -------------------------------------------------------------##
1635
1636AT_SETUP([Missed %merge type warnings when LHS type is declared later])
55f48c48
AD
1637
1638AT_BISON_OPTION_PUSHDEFS
8ee5b538
JD
1639AT_DATA_GRAMMAR([glr-regr18.y],
1640[[%glr-parser
1641
1642%{
cf806753 1643 #include <stdlib.h>
55f48c48 1644 ]AT_YYERROR_DECLARE[
290a8ff2 1645 ]AT_YYLEX_DECLARE[
8ee5b538
JD
1646%}
1647
1648%union {
1649 int type1;
1650 int type2;
dd60572a 1651 int type3;
8ee5b538
JD
1652}
1653
1654%%
1655
1656sym1: sym2 %merge<merge> { $$ = $1; } ;
dd60572a
JD
1657sym2: sym3 %merge<merge> { $$ = $1; } ;
1658sym3: %merge<merge> { $$ = 0; } ;
8ee5b538
JD
1659
1660%type <type1> sym1;
1661%type <type2> sym2;
dd60572a 1662%type <type3> sym3;
8ee5b538
JD
1663
1664%%
55f48c48
AD
1665]AT_YYERROR_DEFINE[
1666]AT_YYLEX_DEFINE()[
8ee5b538
JD
1667int
1668main (void)
1669{
1670 return yyparse ();
1671}
1672]])
55f48c48 1673AT_BISON_OPTION_POPDEFS
8ee5b538 1674
da730230 1675AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
abf3f74b 1676[glr-regr18.y:26.18-24: result type clash on merge function 'merge': <type2> != <type1>
231ed89a 1677glr-regr18.y:25.18-24: previous declaration
abf3f74b 1678glr-regr18.y:27.13-19: result type clash on merge function 'merge': <type3> != <type2>
231ed89a 1679glr-regr18.y:26.18-24: previous declaration
8ee5b538
JD
1680])
1681
1682AT_CLEANUP
71cbc1ac
AD
1683
1684
1685## ------------------- ##
1686## Ambiguity reports. ##
1687## ------------------- ##
1688
1689AT_SETUP([Ambiguity reports])
1690
55f48c48 1691AT_BISON_OPTION_PUSHDEFS
71cbc1ac
AD
1692AT_DATA_GRAMMAR([input.y],
1693[[
1694%{
1695 #include <stdio.h>
1696 #include <stdlib.h>
55f48c48
AD
1697 ]AT_YYERROR_DECLARE[
1698 ]AT_YYLEX_DECLARE[
71cbc1ac
AD
1699%}
1700
1701%debug
1702%glr-parser
1703
1704%%
1705start:
1706 'a' b 'c' d
1707| 'a' b 'c' d
1708;
1709b: 'b';
1710d: /* nada. */;
1711%%
55f48c48
AD
1712]AT_YYLEX_DEFINE([abc])[
1713]AT_YYERROR_DEFINE[
71cbc1ac
AD
1714int
1715main (void)
1716{
1717 yydebug = 1;
1718 return !!yyparse ();
1719}
1720]])
55f48c48 1721AT_BISON_OPTION_POPDEFS
71cbc1ac
AD
1722
1723AT_BISON_CHECK([[-o input.c input.y]], 0, [],
1724[input.y: conflicts: 1 reduce/reduce
1725])
1726AT_COMPILE([input])
1727
1728AT_PARSER_CHECK([[./input]], 1, [],
1729[Starting parse
1730Entering state 0
1731Reading a token: Next token is token 'a' ()
1732Shifting token 'a' ()
1733Entering state 1
1734Reading a token: Next token is token 'b' ()
1735Shifting token 'b' ()
1736Entering state 3
1737Reducing stack 0 by rule 3 (line 25):
1738 $1 = token 'b' ()
1739-> $$ = nterm b ()
1740Entering state 4
1741Reading a token: Next token is token 'c' ()
1742Shifting token 'c' ()
1743Entering state 6
1744Reducing stack 0 by rule 4 (line 26):
1745-> $$ = nterm d ()
1746Entering state 7
1747Reading a token: Now at end of input.
1748Stack 0 Entering state 7
1749Now at end of input.
1750Splitting off stack 1 from 0.
1751Reduced stack 1 by rule #2; action deferred. Now in state 2.
1752Stack 1 Entering state 2
1753Now at end of input.
1754Reduced stack 0 by rule #1; action deferred. Now in state 2.
1755Merging stack 0 into stack 1.
1756Stack 1 Entering state 2
1757Now at end of input.
1758Removing dead stacks.
1759Rename stack 1 -> 0.
1760On stack 0, shifting token $end ()
1761Stack 0 now in state #5
1762Ambiguity detected.
1763Option 1,
1764 start -> <Rule 1, tokens 1 .. 3>
1765 'a' <tokens 1 .. 1>
1766 b <tokens 2 .. 2>
1767 'c' <tokens 3 .. 3>
1768 d <empty>
1769
1770Option 2,
1771 start -> <Rule 2, tokens 1 .. 3>
1772 'a' <tokens 1 .. 1>
1773 b <tokens 2 .. 2>
1774 'c' <tokens 3 .. 3>
1775 d <empty>
1776
1777syntax is ambiguous
1778Cleanup: popping token $end ()
1779Cleanup: popping unresolved nterm start ()
1780Cleanup: popping nterm d ()
1781Cleanup: popping token 'c' ()
1782Cleanup: popping nterm b ()
1783Cleanup: popping token 'a' ()
1784])
1785
1786AT_CLEANUP