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