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