]> git.saurik.com Git - bison.git/blame - tests/glr-regression.at
regen
[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, [],
d87ea54c
AD
96[[glr-regr1.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
97]])
ede3d3bc 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, [],
d87ea54c
AD
211[[glr-regr2a.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
212]])
ede3d3bc
PH
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, [],
d87ea54c
AD
328[[glr-regr3.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
329glr-regr3.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
330]])
5e6f62f2
PH
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 386]AT_YYERROR_DEFINE[
95361618 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, [],
d87ea54c
AD
421[[glr-regr4.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
422]])
f9315de5
PE
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%%
95361618 470]AT_YYLEX_DEFINE(["a"])[
55f48c48 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, [],
d87ea54c
AD
481[[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
482]])
adc90f13
PE
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[
95361618 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, [],
d87ea54c
AD
533[[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
534]])
42a6501d
PE
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, [],
d87ea54c
AD
622[[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
623]])
1bd0deda
PE
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, [],
d87ea54c
AD
716[[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
717]])
44e7ead1
PH
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, [],
d87ea54c
AD
796[[glr-regr9.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
797]])
69ce078b
PE
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[
95361618 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, [],
d87ea54c
AD
852[[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
853]])
d659304d
JD
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 892]AT_YYERROR_DEFINE[
95361618 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, [],
d87ea54c
AD
910[[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
911]])
d659304d
JD
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>
77519a7d 938# include <assert.h>
d659304d 939 static int merge (YYSTYPE, YYSTYPE);
55f48c48
AD
940 ]AT_YYERROR_DECLARE[
941 ]AT_YYLEX_DECLARE[
520181ab
JD
942 static int parent_rhs_before_value = 0;
943 static int merged_value = 0;
944 static int parent_rhs_after_value = 0;
d659304d
JD
945# define USE(val)
946%}
947
948%%
949
950start:
520181ab
JD
951 alt1 %dprec 1
952 | alt2 %dprec 2
6d05403d 953 ;
520181ab
JD
954
955alt1:
956 PARENT_RHS_AFTER {
957 USE ($1);
958 parent_rhs_after_value = 0;
959 }
960 ;
961
962alt2:
963 parent_rhs_before merged PARENT_RHS_AFTER {
964 USE (($1, $2, $3));
965 parent_rhs_before_value = 0;
966 merged_value = 0;
967 parent_rhs_after_value = 0;
968 }
969 ;
970
971parent_rhs_before:
972 {
973 USE ($$);
974 parent_rhs_before_value = 1;
975 }
976 ;
977
978merged:
979 %merge<merge> {
980 USE ($$);
981 merged_value = 1;
982 }
983 | cut %merge<merge> {
984 USE ($$);
985 merged_value = 1;
986 }
d659304d
JD
987 ;
988
520181ab
JD
989cut: { YYACCEPT; } ;
990
d659304d
JD
991%%
992
993static int
994merge (YYSTYPE s1, YYSTYPE s2)
995{
996 /* Not invoked. */
bf70fa87
JD
997 char dummy = s1.dummy + s2.dummy;
998 return dummy;
d659304d
JD
999}
1000
55f48c48 1001]AT_YYERROR_DEFINE[
087dcd78
AD
1002]AT_YYLEX_DEFINE([{ PARENT_RHS_AFTER, 0 }],
1003 [if (res == PARENT_RHS_AFTER)
1004 parent_rhs_after_value = 1;])[
d659304d
JD
1005
1006int
1007main (void)
1008{
1009 int exit_status = yyparse ();
520181ab 1010 if (parent_rhs_before_value)
d659304d 1011 {
520181ab
JD
1012 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1013 exit_status = 1;
1014 }
1015 if (merged_value)
1016 {
1017 fprintf (stderr, "`merged' destructor not called.\n");
1018 exit_status = 1;
1019 }
1020 if (parent_rhs_after_value)
1021 {
1022 fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
1023 exit_status = 1;
d659304d
JD
1024 }
1025 return exit_status;
1026}
1027]])
55f48c48 1028AT_BISON_OPTION_POPDEFS
d659304d 1029
da730230 1030AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [],
d87ea54c
AD
1031[[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
1032glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1033]])
d659304d
JD
1034AT_COMPILE([glr-regr12])
1035
7d2d521f 1036AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
d659304d
JD
1037
1038AT_CLEANUP
bf70fa87
JD
1039
1040
1041## ------------------------------------------------------------------------- ##
1042## Incorrect lookahead during deterministic GLR. See ##
3f001415
JD
1043## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1044## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
bf70fa87
JD
1045## ------------------------------------------------------------------------- ##
1046
1047AT_SETUP([Incorrect lookahead during deterministic GLR])
1048
55f48c48 1049AT_BISON_OPTION_PUSHDEFS
bf70fa87
JD
1050AT_DATA_GRAMMAR([glr-regr13.y],
1051[[
1052/* Tests:
1053 - Defaulted state with initial yychar: yychar == YYEMPTY.
1054 - Nondefaulted state: yychar != YYEMPTY.
1055 - Defaulted state after lookahead: yychar != YYEMPTY.
3f001415
JD
1056 - Defaulted state after shift: yychar == YYEMPTY.
1057 - User action changing the lookahead. */
bf70fa87
JD
1058
1059%{
1060 #include <stdio.h>
77519a7d 1061 #include <assert.h>
55f48c48
AD
1062 ]AT_YYERROR_DECLARE[
1063 ]AT_YYLEX_DECLARE[
742e4900 1064 static void print_lookahead (char const *);
bf70fa87
JD
1065 #define USE(value)
1066%}
1067
1068%union { char value; }
1069%type <value> 'a' 'b'
1070%glr-parser
1071%locations
1072
1073%%
1074
1075start:
3f001415 1076 defstate_init defstate_shift 'b' change_lookahead 'a' {
bf70fa87 1077 USE ($3);
742e4900 1078 print_lookahead ("start <- defstate_init defstate_shift 'b'");
bf70fa87
JD
1079 }
1080 ;
1081defstate_init:
1082 {
742e4900 1083 print_lookahead ("defstate_init <- empty string");
bf70fa87
JD
1084 }
1085 ;
1086defstate_shift:
1087 nondefstate defstate_look 'a' {
1088 USE ($3);
742e4900 1089 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
bf70fa87
JD
1090 }
1091 ;
1092defstate_look:
1093 {
742e4900 1094 print_lookahead ("defstate_look <- empty string");
bf70fa87
JD
1095 }
1096 ;
1097nondefstate:
1098 {
742e4900 1099 print_lookahead ("nondefstate <- empty string");
bf70fa87
JD
1100 }
1101 | 'b' {
1102 USE ($1);
742e4900 1103 print_lookahead ("nondefstate <- 'b'");
bf70fa87
JD
1104 }
1105 ;
3f001415
JD
1106change_lookahead:
1107 {
1108 yychar = 'a';
1109 }
1110 ;
bf70fa87
JD
1111
1112%%
1113
55f48c48 1114]AT_YYERROR_DEFINE[
087dcd78
AD
1115]AT_YYLEX_DEFINE(["ab"],
1116 [yylval.value = res + 'A' - 'a'])[
bf70fa87
JD
1117
1118static void
742e4900 1119print_lookahead (char const *reduction)
bf70fa87
JD
1120{
1121 printf ("%s:\n yychar=", reduction);
1122 if (yychar == YYEMPTY)
1123 printf ("YYEMPTY");
1124 else if (yychar == YYEOF)
1125 printf ("YYEOF");
1126 else
1127 {
1128 printf ("'%c', yylval='", yychar);
1129 if (yylval.value > ' ')
1130 printf ("%c", yylval.value);
1131 printf ("', yylloc=(%d,%d),(%d,%d)",
1132 yylloc.first_line, yylloc.first_column,
1133 yylloc.last_line, yylloc.last_column);
1134 }
1135 printf ("\n");
1136}
1137
1138int
1139main (void)
1140{
1141 yychar = '#'; /* Not a token in the grammar. */
1142 yylval.value = '!';
1143 return yyparse ();
1144}
1145]])
55f48c48 1146AT_BISON_OPTION_POPDEFS
bf70fa87 1147
da730230 1148AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], [])
bf70fa87
JD
1149AT_COMPILE([glr-regr13])
1150
7d2d521f 1151AT_PARSER_CHECK([[./glr-regr13]], 0,
bf70fa87
JD
1152[defstate_init <- empty string:
1153 yychar=YYEMPTY
1154nondefstate <- empty string:
1155 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1156defstate_look <- empty string:
1157 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1158defstate_shift <- nondefstate defstate_look 'a':
1159 yychar=YYEMPTY
1160start <- defstate_init defstate_shift 'b':
1161 yychar=YYEMPTY
1162], [])
1163
1164AT_CLEANUP
1165
1166
1167## ------------------------------------------------------------------------- ##
1168## Incorrect lookahead during nondeterministic GLR. ##
1169## ------------------------------------------------------------------------- ##
1170
1171AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1172
55f48c48 1173AT_BISON_OPTION_PUSHDEFS
bf70fa87
JD
1174AT_DATA_GRAMMAR([glr-regr14.y],
1175[[
1176/* Tests:
b7691f15 1177 - Conflicting actions (split-off parse, which copies lookahead need,
bf70fa87
JD
1178 which is necessarily yytrue) and nonconflicting actions (non-split-off
1179 parse) for nondefaulted state: yychar != YYEMPTY.
b7691f15 1180 - Merged deferred actions (lookahead need and RHS from different stack
bf70fa87
JD
1181 than the target state) and nonmerged deferred actions (same stack).
1182 - Defaulted state after lookahead: yychar != YYEMPTY.
1183 - Defaulted state after shift: yychar == YYEMPTY.
b7691f15 1184 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
bf70fa87
JD
1185 seen the lookahead but current stack has not).
1186 - Exceeding stack capacity (stack explosion), and thus reallocating
b7691f15 1187 lookahead need array.
bf70fa87
JD
1188 Note that it does not seem possible to see the initial yychar value during
1189 nondeterministic operation since:
1190 - In order to preserve the initial yychar, only defaulted states may be
1191 entered.
1192 - If only defaulted states are entered, there are no conflicts, so
1193 nondeterministic operation does not start. */
1194
1195%union { char value; }
1196
1197%{
cf806753 1198 #include <stdlib.h>
bf70fa87 1199 #include <stdio.h>
77519a7d 1200 #include <assert.h>
55f48c48
AD
1201 ]AT_YYERROR_DECLARE[
1202 ]AT_YYLEX_DECLARE[
742e4900 1203 static void print_lookahead (char const *);
bf70fa87
JD
1204 static char merge (union YYSTYPE, union YYSTYPE);
1205 #define USE(value)
1206%}
1207
1208%type <value> 'a' 'b' 'c' 'd' stack_explosion
1209%glr-parser
1210%locations
1211
1212%%
1213
1214start:
1215 merge 'c' stack_explosion {
1216 USE ($2); USE ($3);
742e4900 1217 print_lookahead ("start <- merge 'c' stack_explosion");
bf70fa87
JD
1218 }
1219 ;
1220
b7691f15 1221/* When merging the 2 deferred actions, the lookahead needs are different. */
bf70fa87
JD
1222merge:
1223 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1224 USE ($2); USE ($3);
742e4900 1225 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
bf70fa87
JD
1226 }
1227 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1228 USE ($3); USE ($5);
742e4900 1229 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
bf70fa87
JD
1230 " defstate_shift");
1231 }
1232 ;
1233
1234nonconflict1:
1235 {
742e4900 1236 print_lookahead ("nonconflict1 <- empty string");
bf70fa87
JD
1237 }
1238 ;
1239nonconflict2:
1240 {
742e4900 1241 print_lookahead ("nonconflict2 <- empty string");
bf70fa87
JD
1242 }
1243 | 'a' {
1244 USE ($1);
742e4900 1245 print_lookahead ("nonconflict2 <- 'a'");
bf70fa87
JD
1246 }
1247 ;
1248conflict:
1249 {
742e4900 1250 print_lookahead ("conflict <- empty string");
bf70fa87
JD
1251 }
1252 ;
1253defstate_look:
1254 {
742e4900 1255 print_lookahead ("defstate_look <- empty string");
bf70fa87
JD
1256 }
1257 ;
1258
b7691f15 1259/* yychar != YYEMPTY but lookahead need is yyfalse. */
bf70fa87
JD
1260defstate_shift:
1261 {
742e4900 1262 print_lookahead ("defstate_shift <- empty string");
bf70fa87
JD
1263 }
1264 ;
1265
1266stack_explosion:
1267 { $$ = '\0'; }
1268 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1269 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1270 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1271 ;
1272alt1:
1273 'd' no_look {
1274 USE ($1);
1275 if (yychar != 'd' && yychar != YYEOF)
1276 {
1277 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1278 }
1279 }
1280 ;
1281alt2:
1282 'd' no_look {
1283 USE ($1);
1284 if (yychar != 'd' && yychar != YYEOF)
1285 {
1286 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1287 }
1288 }
1289 ;
1290alt3:
1291 'd' no_look {
1292 USE ($1);
1293 if (yychar != 'd' && yychar != YYEOF)
1294 {
1295 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1296 }
1297 }
1298 ;
1299no_look:
1300 {
1301 if (yychar != YYEMPTY)
1302 {
1303 fprintf (stderr,
1304 "Found lookahead where shouldn't during stack explosion.\n");
1305 }
1306 }
1307 ;
1308
1309%%
1310
55f48c48 1311]AT_YYERROR_DEFINE[
bf70fa87
JD
1312static int
1313yylex (void)
1314{
cf806753
PE
1315 static char const input[] = "abcdddd";
1316 static size_t toknum;
77519a7d 1317 assert (toknum < sizeof input);
bf70fa87 1318 yylloc.first_line = yylloc.last_line = 1;
cf806753
PE
1319 yylloc.first_column = yylloc.last_column = toknum + 1;
1320 yylval.value = input[toknum] + 'A' - 'a';
1321 return input[toknum++];
bf70fa87
JD
1322}
1323
1324static void
742e4900 1325print_lookahead (char const *reduction)
bf70fa87
JD
1326{
1327 printf ("%s:\n yychar=", reduction);
1328 if (yychar == YYEMPTY)
1329 printf ("YYEMPTY");
1330 else if (yychar == YYEOF)
1331 printf ("YYEOF");
1332 else
1333 {
1334 printf ("'%c', yylval='", yychar);
1335 if (yylval.value > ' ')
1336 printf ("%c", yylval.value);
1337 printf ("', yylloc=(%d,%d),(%d,%d)",
1338 yylloc.first_line, yylloc.first_column,
1339 yylloc.last_line, yylloc.last_column);
1340 }
1341 printf ("\n");
1342}
1343
1344static char
1345merge (union YYSTYPE s1, union YYSTYPE s2)
1346{
1347 char dummy = s1.value + s2.value;
1348 return dummy;
1349}
1350
1351int
1352main (void)
1353{
1354 yychar = '#'; /* Not a token in the grammar. */
1355 yylval.value = '!';
1356 return yyparse ();
1357}
1358]])
55f48c48 1359AT_BISON_OPTION_POPDEFS
bf70fa87 1360
da730230 1361AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
d87ea54c
AD
1362[[glr-regr14.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1363]])
bf70fa87
JD
1364AT_COMPILE([glr-regr14])
1365
7d2d521f 1366AT_PARSER_CHECK([[./glr-regr14]], 0,
bf70fa87
JD
1367[conflict <- empty string:
1368 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1369defstate_look <- empty string:
1370 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1371nonconflict2 <- empty string:
1372 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1373defstate_shift <- empty string:
1374 yychar=YYEMPTY
1375merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1376 yychar=YYEMPTY
1377start <- merge 'c' stack_explosion:
1378 yychar=YYEOF
1379], [])
1380
1381AT_CLEANUP
35ee866a
JD
1382
1383
1384## ------------------------------------------------------------------------- ##
1385## Leaked semantic values when reporting ambiguity. ##
1386## ------------------------------------------------------------------------- ##
1387
1388AT_SETUP([Leaked semantic values when reporting ambiguity])
1389
55f48c48 1390AT_BISON_OPTION_PUSHDEFS
35ee866a
JD
1391AT_DATA_GRAMMAR([glr-regr15.y],
1392[[
1393%glr-parser
35ee866a
JD
1394%destructor { parent_rhs_before_value = 0; } parent_rhs_before
1395
1396%{
1397# include <stdlib.h>
55f48c48
AD
1398 ]AT_YYERROR_DECLARE[
1399 ]AT_YYLEX_DECLARE[
35ee866a
JD
1400 static int parent_rhs_before_value = 0;
1401# define USE(val)
1402%}
1403
1404%%
1405
1406start:
1407 alt1 %dprec 1
1408 | alt2 %dprec 2
1409 ;
1410
1411/* This stack must be merged into the other stacks *last* (added at the
1412 beginning of the semantic options list) so that yyparse will choose to clean
1413 it up rather than the tree for which some semantic actions have been
1414 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1415 those other trees are not cleaned up. */
1416alt1: ;
1417
1418alt2:
1419 parent_rhs_before ambiguity {
1420 USE ($1);
1421 parent_rhs_before_value = 0;
1422 }
1423 ;
1424
1425parent_rhs_before:
1426 {
1427 USE ($$);
1428 parent_rhs_before_value = 1;
1429 }
1430 ;
1431
1432ambiguity: ambiguity1 | ambiguity2 ;
1433ambiguity1: ;
1434ambiguity2: ;
1435
1436%%
55f48c48 1437]AT_YYERROR_DEFINE[
95361618 1438]AT_YYLEX_DEFINE[
35ee866a
JD
1439
1440int
1441main (void)
1442{
1443 int exit_status = yyparse () != 1;
1444 if (parent_rhs_before_value)
1445 {
1446 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1447 exit_status = 1;
1448 }
1449 return exit_status;
1450}
1451]])
55f48c48 1452AT_BISON_OPTION_POPDEFS
35ee866a 1453
da730230 1454AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
d87ea54c
AD
1455[[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
1456]])
35ee866a
JD
1457AT_COMPILE([glr-regr15])
1458
7d2d521f 1459AT_PARSER_CHECK([[./glr-regr15]], 0, [],
35ee866a
JD
1460[syntax is ambiguous
1461])
1462
1463AT_CLEANUP
ae952af2
JD
1464
1465
1466## ------------------------------------------------------------------------- ##
1467## Leaked lookahead after nondeterministic parse syntax error. ##
1468## ------------------------------------------------------------------------- ##
1469
1470AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
55f48c48
AD
1471
1472AT_BISON_OPTION_PUSHDEFS
ae952af2
JD
1473AT_DATA_GRAMMAR([glr-regr16.y],
1474[[
1475%glr-parser
1476%destructor { lookahead_value = 0; } 'b'
1477
1478%{
1479# include <stdlib.h>
77519a7d 1480# include <assert.h>
55f48c48
AD
1481 ]AT_YYERROR_DECLARE[
1482 ]AT_YYLEX_DECLARE[
ae952af2
JD
1483 static int lookahead_value = 0;
1484# define USE(val)
1485%}
1486
1487%%
1488
1489start: alt1 'a' | alt2 'a' ;
1490alt1: ;
1491alt2: ;
1492
1493%%
1494
55f48c48 1495]AT_YYERROR_DEFINE[
087dcd78
AD
1496]AT_YYLEX_DEFINE(["ab"],
1497 [if (res == 'b')
1498 lookahead_value = 1])[
ae952af2
JD
1499
1500int
1501main (void)
1502{
1503 int exit_status = yyparse () != 1;
1504 if (lookahead_value)
1505 {
1506 fprintf (stderr, "Lookahead destructor not called.\n");
1507 exit_status = 1;
1508 }
1509 return exit_status;
1510}
1511]])
55f48c48 1512AT_BISON_OPTION_POPDEFS
ae952af2 1513
da730230 1514AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
d87ea54c
AD
1515[[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1516]])
ae952af2
JD
1517AT_COMPILE([glr-regr16])
1518
7d2d521f 1519AT_PARSER_CHECK([[./glr-regr16]], 0, [],
ae952af2
JD
1520[syntax error
1521])
1522
1523AT_CLEANUP
8710fc41
JD
1524
1525
1526## ------------------------------------------------------------------------- ##
1527## Uninitialized location when reporting ambiguity. ##
1528## ------------------------------------------------------------------------- ##
1529
1530AT_SETUP([Uninitialized location when reporting ambiguity])
55f48c48 1531
8d6c1b5e
AD
1532AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations %define api.pure])
1533
8710fc41
JD
1534AT_DATA_GRAMMAR([glr-regr17.y],
1535[[
1536%glr-parser
1537%locations
d9df47b6 1538%define api.pure
8710fc41
JD
1539%error-verbose
1540
1541%union { int dummy; }
1542
1543%{
8d6c1b5e
AD
1544 ]AT_YYERROR_DECLARE[
1545 ]AT_YYLEX_DECLARE[
8710fc41
JD
1546%}
1547
1548%initial-action {
1549 @$.first_line = 1;
1550 @$.first_column = 1;
1551 @$.last_line = 1;
1552 @$.last_column = 1;
1553}
1554
1555%%
1556
5ad0a449
JD
1557/* Tests the case of an empty RHS that has inherited the location of the
1558 previous nonterminal, which is unresolved. That location is reported as the
1559 last position of the ambiguity. */
1560start: ambig1 empty1 | ambig2 empty2 ;
1561
8710fc41 1562/* Tests multiple levels of yyresolveLocations recursion. */
8710fc41
JD
1563ambig1: sub_ambig1 | sub_ambig2 ;
1564ambig2: sub_ambig1 | sub_ambig2 ;
1565
5ad0a449
JD
1566/* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1567 has inherited the initial location. The empty RHS's location is reported as
1568 the first position in the ambiguity. */
1569sub_ambig1: empty1 'a' 'b' ;
1570sub_ambig2: empty2 'a' 'b' ;
1571empty1: ;
1572empty2: ;
8710fc41
JD
1573
1574%%
77519a7d 1575# include <assert.h>
8710fc41 1576
8d6c1b5e 1577]AT_YYERROR_DEFINE[
6d05403d 1578static int
8710fc41
JD
1579yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1580{
6d05403d 1581 static char const input[] = "ab";
cf806753 1582 static size_t toknum;
77519a7d 1583 assert (toknum < sizeof input);
6d05403d 1584 lvalp->dummy = 0;
8710fc41 1585 llocp->first_line = llocp->last_line = 2;
cf806753 1586 llocp->first_column = toknum + 1;
8710fc41 1587 llocp->last_column = llocp->first_column + 1;
cf806753 1588 return input[toknum++];
8710fc41
JD
1589}
1590
1591int
1592main (void)
1593{
1594 return yyparse () != 1;
1595}
1596]])
55f48c48 1597AT_BISON_OPTION_POPDEFS
8710fc41 1598
da730230 1599AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [],
d87ea54c
AD
1600[[glr-regr17.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1601]])
8710fc41
JD
1602AT_COMPILE([glr-regr17])
1603
7d2d521f 1604AT_PARSER_CHECK([[./glr-regr17]], 0, [],
8d6c1b5e 1605[1.1-2.2: syntax is ambiguous
8710fc41
JD
1606])
1607
1608AT_CLEANUP
8ee5b538
JD
1609
1610
1611## -------------------------------------------------------------##
1612## Missed %merge type warnings when LHS type is declared later. ##
1613## -------------------------------------------------------------##
1614
1615AT_SETUP([Missed %merge type warnings when LHS type is declared later])
55f48c48
AD
1616
1617AT_BISON_OPTION_PUSHDEFS
8ee5b538
JD
1618AT_DATA_GRAMMAR([glr-regr18.y],
1619[[%glr-parser
1620
1621%{
cf806753 1622 #include <stdlib.h>
55f48c48 1623 ]AT_YYERROR_DECLARE[
290a8ff2 1624 ]AT_YYLEX_DECLARE[
8ee5b538
JD
1625%}
1626
1627%union {
1628 int type1;
1629 int type2;
dd60572a 1630 int type3;
8ee5b538
JD
1631}
1632
1633%%
1634
1635sym1: sym2 %merge<merge> { $$ = $1; } ;
dd60572a
JD
1636sym2: sym3 %merge<merge> { $$ = $1; } ;
1637sym3: %merge<merge> { $$ = 0; } ;
8ee5b538
JD
1638
1639%type <type1> sym1;
1640%type <type2> sym2;
dd60572a 1641%type <type3> sym3;
8ee5b538
JD
1642
1643%%
55f48c48 1644]AT_YYERROR_DEFINE[
95361618 1645]AT_YYLEX_DEFINE[
8ee5b538
JD
1646int
1647main (void)
1648{
1649 return yyparse ();
1650}
1651]])
55f48c48 1652AT_BISON_OPTION_POPDEFS
8ee5b538 1653
da730230 1654AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
abf3f74b 1655[glr-regr18.y:26.18-24: result type clash on merge function 'merge': <type2> != <type1>
231ed89a 1656glr-regr18.y:25.18-24: previous declaration
abf3f74b 1657glr-regr18.y:27.13-19: result type clash on merge function 'merge': <type3> != <type2>
231ed89a 1658glr-regr18.y:26.18-24: previous declaration
8ee5b538
JD
1659])
1660
1661AT_CLEANUP
71cbc1ac
AD
1662
1663
1664## ------------------- ##
1665## Ambiguity reports. ##
1666## ------------------- ##
1667
1668AT_SETUP([Ambiguity reports])
1669
55f48c48 1670AT_BISON_OPTION_PUSHDEFS
71cbc1ac
AD
1671AT_DATA_GRAMMAR([input.y],
1672[[
1673%{
1674 #include <stdio.h>
1675 #include <stdlib.h>
55f48c48
AD
1676 ]AT_YYERROR_DECLARE[
1677 ]AT_YYLEX_DECLARE[
71cbc1ac
AD
1678%}
1679
1680%debug
1681%glr-parser
1682
1683%%
1684start:
1685 'a' b 'c' d
1686| 'a' b 'c' d
1687;
1688b: 'b';
1689d: /* nada. */;
1690%%
95361618 1691]AT_YYLEX_DEFINE(["abc"])[
55f48c48 1692]AT_YYERROR_DEFINE[
71cbc1ac
AD
1693int
1694main (void)
1695{
1696 yydebug = 1;
1697 return !!yyparse ();
1698}
1699]])
55f48c48 1700AT_BISON_OPTION_POPDEFS
71cbc1ac
AD
1701
1702AT_BISON_CHECK([[-o input.c input.y]], 0, [],
d87ea54c
AD
1703[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1704]])
71cbc1ac
AD
1705AT_COMPILE([input])
1706
1707AT_PARSER_CHECK([[./input]], 1, [],
1708[Starting parse
1709Entering state 0
1710Reading a token: Next token is token 'a' ()
1711Shifting token 'a' ()
1712Entering state 1
1713Reading a token: Next token is token 'b' ()
1714Shifting token 'b' ()
1715Entering state 3
1716Reducing stack 0 by rule 3 (line 25):
1717 $1 = token 'b' ()
1718-> $$ = nterm b ()
1719Entering state 4
1720Reading a token: Next token is token 'c' ()
1721Shifting token 'c' ()
1722Entering state 6
1723Reducing stack 0 by rule 4 (line 26):
1724-> $$ = nterm d ()
1725Entering state 7
1726Reading a token: Now at end of input.
1727Stack 0 Entering state 7
1728Now at end of input.
1729Splitting off stack 1 from 0.
1730Reduced stack 1 by rule #2; action deferred. Now in state 2.
1731Stack 1 Entering state 2
1732Now at end of input.
1733Reduced stack 0 by rule #1; action deferred. Now in state 2.
1734Merging stack 0 into stack 1.
1735Stack 1 Entering state 2
1736Now at end of input.
1737Removing dead stacks.
1738Rename stack 1 -> 0.
1739On stack 0, shifting token $end ()
1740Stack 0 now in state #5
1741Ambiguity detected.
1742Option 1,
1743 start -> <Rule 1, tokens 1 .. 3>
1744 'a' <tokens 1 .. 1>
1745 b <tokens 2 .. 2>
1746 'c' <tokens 3 .. 3>
1747 d <empty>
1748
1749Option 2,
1750 start -> <Rule 2, tokens 1 .. 3>
1751 'a' <tokens 1 .. 1>
1752 b <tokens 2 .. 2>
1753 'c' <tokens 3 .. 3>
1754 d <empty>
1755
1756syntax is ambiguous
1757Cleanup: popping token $end ()
1758Cleanup: popping unresolved nterm start ()
1759Cleanup: popping nterm d ()
1760Cleanup: popping token 'c' ()
1761Cleanup: popping nterm b ()
1762Cleanup: popping token 'a' ()
1763])
1764
1765AT_CLEANUP