]> git.saurik.com Git - bison.git/blame - tests/glr-regression.at
tests: be robust to set -e.
[bison.git] / tests / glr-regression.at
CommitLineData
ede3d3bc 1# Checking GLR Parsing: Regression Tests -*- Autotest -*-
6e30ede8 2
c932d613 3# Copyright (C) 2002-2003, 2005-2007, 2009-2012 Free Software
38609c34 4# Foundation, Inc.
ede3d3bc 5
f16b0819 6# This program is free software: you can redistribute it and/or modify
ede3d3bc 7# it under the terms of the GNU General Public License as published by
f16b0819
PE
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
ede3d3bc
PH
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
f16b0819 15#
ede3d3bc 16# You should have received a copy of the GNU General Public License
f16b0819 17# along with this program. If not, see <http://www.gnu.org/licenses/>.
ede3d3bc
PH
18
19AT_BANNER([[GLR Regression Tests]])
20
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
AD
328int
329main(int argc, char* argv[])
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[
adc90f13
PE
491int
492main (void)
493{
494 return yyparse () != 1;
495}
496]])
55f48c48 497AT_BISON_OPTION_POPDEFS
adc90f13 498
da730230 499AT_BISON_CHECK([[-o glr-regr5.c glr-regr5.y]], 0, [],
d87ea54c
AD
500[[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
501]])
adc90f13
PE
502AT_COMPILE([glr-regr5])
503
7d2d521f 504AT_PARSER_CHECK([[./glr-regr5]], 0, [],
42a6501d
PE
505[syntax is ambiguous
506])
507
508AT_CLEANUP
509
510
c8e966e2
AD
511## ------------------------------------------------------------------------- ##
512## User destructor after an error during a split parse. See ##
513## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>. ##
514## ------------------------------------------------------------------------- ##
42a6501d
PE
515
516AT_SETUP([User destructor after an error during a split parse])
517
55f48c48 518AT_BISON_OPTION_PUSHDEFS
42a6501d 519AT_DATA_GRAMMAR([glr-regr6.y],
1bd0deda
PE
520[[
521%{
42a6501d
PE
522 #include <stdio.h>
523 #include <stdlib.h>
55f48c48
AD
524 ]AT_YYERROR_DECLARE[
525 ]AT_YYLEX_DECLARE[
42a6501d
PE
526%}
527
528%glr-parser
529%union { int value; }
530%type <value> 'a'
531
532%destructor {
533 printf ("Destructor called.\n");
534} 'a'
535
536%%
537
538start: 'a' | 'a' ;
539
540%%
55f48c48 541]AT_YYERROR_DEFINE[
95361618 542]AT_YYLEX_DEFINE(["a"])[
42a6501d
PE
543int
544main (void)
545{
546 return yyparse () != 1;
547}
548]])
55f48c48 549AT_BISON_OPTION_POPDEFS
42a6501d 550
da730230 551AT_BISON_CHECK([[-o glr-regr6.c glr-regr6.y]], 0, [],
d87ea54c
AD
552[[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
553]])
42a6501d
PE
554AT_COMPILE([glr-regr6])
555
7d2d521f 556AT_PARSER_CHECK([[./glr-regr6]], 0,
42a6501d
PE
557[Destructor called.
558],
adc90f13
PE
559[syntax is ambiguous
560])
561
562AT_CLEANUP
1bd0deda
PE
563
564
565## ------------------------------------------------------------------------- ##
c8e966e2 566## Duplicated user destructor for lookahead. See ##
1bd0deda
PE
567## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>. ##
568## ------------------------------------------------------------------------- ##
569
570AT_SETUP([Duplicated user destructor for lookahead])
571
55f48c48 572AT_BISON_OPTION_PUSHDEFS
1bd0deda
PE
573AT_DATA_GRAMMAR([glr-regr7.y],
574[[
575%{
576 #include <stdio.h>
577 #include <stdlib.h>
55f48c48
AD
578 ]AT_YYERROR_DECLARE[
579 ]AT_YYLEX_DECLARE[
1bd0deda 580 #define YYSTACKEXPANDABLE 0
7d2d521f
JD
581 typedef struct count_node {
582 int count;
583 struct count_node *prev;
584 } count_node;
585 static count_node *tail;
1bd0deda
PE
586%}
587
588%glr-parser
7d2d521f
JD
589%union { count_node *node; }
590%type <node> 'a'
1bd0deda
PE
591
592%destructor {
7d2d521f 593 if ($$->count++)
1bd0deda
PE
594 fprintf (stderr, "Destructor called on same value twice.\n");
595} 'a'
596
597%%
598
599start:
600 stack1 start
601 | stack2 start
602 | /* empty */
603 ;
604stack1: 'a' ;
605stack2: 'a' ;
606
607%%
608
609static int
610yylex (void)
611{
7d2d521f
JD
612 yylval.node = (count_node*) malloc (sizeof *yylval.node);
613 if (!yylval.node)
1bd0deda
PE
614 {
615 fprintf (stderr, "Test inconclusive.\n");
616 exit (EXIT_FAILURE);
617 }
7d2d521f
JD
618 yylval.node->count = 0;
619 yylval.node->prev = tail;
620 tail = yylval.node;
1bd0deda
PE
621 return 'a';
622}
623
55f48c48 624]AT_YYERROR_DEFINE[
1bd0deda
PE
625int
626main (void)
627{
7d2d521f
JD
628 int status = yyparse ();
629 while (tail)
630 {
631 count_node *prev = tail->prev;
632 free (tail);
633 tail = prev;
634 }
635 return status;
1bd0deda
PE
636}
637]])
55f48c48 638AT_BISON_OPTION_POPDEFS
1bd0deda 639
da730230 640AT_BISON_CHECK([[-o glr-regr7.c glr-regr7.y]], 0, [],
d87ea54c
AD
641[[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
642]])
1bd0deda
PE
643AT_COMPILE([glr-regr7])
644
7d2d521f 645AT_PARSER_CHECK([[./glr-regr7]], 2, [],
1bd0deda
PE
646[memory exhausted
647])
648
649AT_CLEANUP
44e7ead1
PH
650
651
652## ------------------------------------------------------------------------- ##
653## Incorrect default location for empty right-hand sides. Adapted from bug ##
654## report by Claudia Hermann. ##
655## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
656## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html ##
657## ------------------------------------------------------------------------- ##
658
659AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
660
55f48c48 661AT_BISON_OPTION_PUSHDEFS
44e7ead1
PH
662AT_DATA_GRAMMAR([glr-regr8.y],
663[[
664%{
665 #include <stdio.h>
666 #include <stdlib.h>
55f48c48
AD
667 ]AT_YYERROR_DECLARE[
668 ]AT_YYLEX_DECLARE[
44e7ead1
PH
669%}
670
671%token T_CONSTANT
672%token T_PORT
673%token T_SIGNAL
674
675%glr-parser
676
677%%
678
679
680PortClause : T_PORT InterfaceDeclaration T_PORT
69ce078b
PE
681 { printf("%d/%d - %d/%d - %d/%d\n",
682 @1.first_column, @1.last_column,
683 @2.first_column, @2.last_column,
44e7ead1
PH
684 @3.first_column, @3.last_column); }
685 ;
686
687InterfaceDeclaration : OptConstantWord %dprec 1
688 | OptSignalWord %dprec 2
689 ;
690
691OptConstantWord : /* empty */
692 | T_CONSTANT
693 ;
694
695OptSignalWord : /* empty */
696 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
697 | T_SIGNAL
698 ;
699
700%%
701
55f48c48 702]AT_YYERROR_DEFINE[
44e7ead1
PH
703static int lexIndex;
704
69ce078b 705int yylex (void)
44e7ead1
PH
706{
707 lexIndex += 1;
708 switch (lexIndex)
709 {
cf806753
PE
710 default:
711 abort ();
44e7ead1
PH
712 case 1:
713 yylloc.first_column = 1;
714 yylloc.last_column = 9;
715 return T_PORT;
716 case 2:
717 yylloc.first_column = 13;
718 yylloc.last_column = 17;
719 return T_PORT;
cf806753 720 case 3:
44e7ead1
PH
721 return 0;
722 }
723}
724
725int
69ce078b 726main (void)
44e7ead1
PH
727{
728 yyparse();
729 return 0;
730}
731]])
55f48c48 732AT_BISON_OPTION_POPDEFS
44e7ead1 733
da730230 734AT_BISON_CHECK([[-o glr-regr8.c glr-regr8.y]], 0, [],
d87ea54c
AD
735[[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
736]])
44e7ead1
PH
737AT_COMPILE([glr-regr8])
738
7d2d521f 739AT_PARSER_CHECK([[./glr-regr8]], 0,
44e7ead1
PH
740[empty: 9/9
7411/9 - 9/9 - 13/17
742],
743[])
744
745AT_CLEANUP
69ce078b
PE
746
747
748## ------------------------------------------------------------------------- ##
c8e966e2 749## No users destructors if stack 0 deleted. See ##
69ce078b
PE
750## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
751## ------------------------------------------------------------------------- ##
752
753AT_SETUP([No users destructors if stack 0 deleted])
754
55f48c48 755AT_BISON_OPTION_PUSHDEFS
69ce078b
PE
756AT_DATA_GRAMMAR([glr-regr9.y],
757[[
758%{
affac613
AD
759# include <stdio.h>
760# include <stdlib.h>
55f48c48
AD
761 ]AT_YYERROR_DECLARE[
762 ]AT_YYLEX_DECLARE[
affac613 763# define YYSTACKEXPANDABLE 0
69ce078b
PE
764 static int tokens = 0;
765 static int destructors = 0;
affac613 766# define USE(Var)
69ce078b
PE
767%}
768
769%glr-parser
770%union { int dummy; }
771%type <dummy> 'a'
772
773%destructor {
774 destructors += 1;
775} 'a'
776
777%%
778
779start:
affac613 780 ambig0 'a' { destructors += 2; USE ($2); }
69ce078b
PE
781 | ambig1 start { destructors += 1; }
782 | ambig2 start { destructors += 1; }
783 ;
784
785ambig0: 'a' ;
786ambig1: 'a' ;
787ambig2: 'a' ;
788
789%%
790
791static int
792yylex (void)
793{
794 tokens += 1;
795 return 'a';
796}
797
55f48c48 798]AT_YYERROR_DEFINE[
69ce078b
PE
799int
800main (void)
801{
802 int exit_status;
803 exit_status = yyparse ();
804 if (tokens != destructors)
805 {
806 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
807 return 1;
808 }
809 return !exit_status;
810}
811]])
55f48c48 812AT_BISON_OPTION_POPDEFS
69ce078b 813
da730230 814AT_BISON_CHECK([[-o glr-regr9.c glr-regr9.y]], 0, [],
d87ea54c
AD
815[[glr-regr9.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
816]])
69ce078b
PE
817AT_COMPILE([glr-regr9])
818
7d2d521f 819AT_PARSER_CHECK([[./glr-regr9]], 0, [],
69ce078b
PE
820[memory exhausted
821])
822
823AT_CLEANUP
d659304d
JD
824
825
c8e966e2
AD
826## ------------------------------------------------------ ##
827## Corrupted semantic options if user action cuts parse. ##
828## ------------------------------------------------------ ##
d659304d 829
bf70fa87 830AT_SETUP([Corrupted semantic options if user action cuts parse])
d659304d 831
55f48c48 832AT_BISON_OPTION_PUSHDEFS
d659304d
JD
833AT_DATA_GRAMMAR([glr-regr10.y],
834[[
835%{
cf806753 836# include <stdlib.h>
d659304d 837# include <stdio.h>
55f48c48
AD
838 ]AT_YYERROR_DECLARE[
839 ]AT_YYLEX_DECLARE[
d659304d
JD
840 #define GARBAGE_SIZE 50
841 static char garbage[GARBAGE_SIZE];
842%}
843
844%glr-parser
845%union { char *ptr; }
846%type <ptr> start
847
848%%
849
850start:
851 %dprec 2 { $$ = garbage; YYACCEPT; }
852 | %dprec 1 { $$ = garbage; YYACCEPT; }
853 ;
854
855%%
55f48c48 856]AT_YYERROR_DEFINE[
95361618 857]AT_YYLEX_DEFINE[
d659304d
JD
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, [],
d87ea54c
AD
871[[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
872]])
d659304d
JD
873AT_COMPILE([glr-regr10])
874
7d2d521f 875AT_PARSER_CHECK([[./glr-regr10]], 0, [], [])
d659304d
JD
876
877AT_CLEANUP
878
879
c8e966e2
AD
880## --------------------------------------------------- ##
881## Undesirable destructors if user action cuts parse. ##
882## --------------------------------------------------- ##
d659304d 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 911]AT_YYERROR_DEFINE[
95361618 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, [],
d87ea54c
AD
929[[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
930]])
d659304d
JD
931AT_COMPILE([glr-regr11])
932
7d2d521f 933AT_PARSER_CHECK([[./glr-regr11]], 0, [], [])
d659304d
JD
934
935AT_CLEANUP
936
937
c8e966e2
AD
938## -------------------------------------------------- ##
939## Leaked semantic values if user action cuts parse. ##
940## -------------------------------------------------- ##
d659304d 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>
77519a7d 957# include <assert.h>
d659304d 958 static int merge (YYSTYPE, YYSTYPE);
55f48c48
AD
959 ]AT_YYERROR_DECLARE[
960 ]AT_YYLEX_DECLARE[
520181ab
JD
961 static int parent_rhs_before_value = 0;
962 static int merged_value = 0;
963 static int parent_rhs_after_value = 0;
d659304d
JD
964# define USE(val)
965%}
966
967%%
968
969start:
520181ab
JD
970 alt1 %dprec 1
971 | alt2 %dprec 2
6d05403d 972 ;
520181ab
JD
973
974alt1:
975 PARENT_RHS_AFTER {
976 USE ($1);
977 parent_rhs_after_value = 0;
978 }
979 ;
980
981alt2:
982 parent_rhs_before merged PARENT_RHS_AFTER {
983 USE (($1, $2, $3));
984 parent_rhs_before_value = 0;
985 merged_value = 0;
986 parent_rhs_after_value = 0;
987 }
988 ;
989
990parent_rhs_before:
991 {
992 USE ($$);
993 parent_rhs_before_value = 1;
994 }
995 ;
996
997merged:
998 %merge<merge> {
999 USE ($$);
1000 merged_value = 1;
1001 }
1002 | cut %merge<merge> {
1003 USE ($$);
1004 merged_value = 1;
1005 }
d659304d
JD
1006 ;
1007
520181ab
JD
1008cut: { YYACCEPT; } ;
1009
d659304d
JD
1010%%
1011
1012static int
1013merge (YYSTYPE s1, YYSTYPE s2)
1014{
1015 /* Not invoked. */
bf70fa87
JD
1016 char dummy = s1.dummy + s2.dummy;
1017 return dummy;
d659304d
JD
1018}
1019
55f48c48 1020]AT_YYERROR_DEFINE[
087dcd78
AD
1021]AT_YYLEX_DEFINE([{ PARENT_RHS_AFTER, 0 }],
1022 [if (res == PARENT_RHS_AFTER)
1023 parent_rhs_after_value = 1;])[
d659304d
JD
1024
1025int
1026main (void)
1027{
1028 int exit_status = yyparse ();
520181ab 1029 if (parent_rhs_before_value)
d659304d 1030 {
520181ab
JD
1031 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1032 exit_status = 1;
1033 }
1034 if (merged_value)
1035 {
1036 fprintf (stderr, "`merged' destructor not called.\n");
1037 exit_status = 1;
1038 }
1039 if (parent_rhs_after_value)
1040 {
1041 fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
1042 exit_status = 1;
d659304d
JD
1043 }
1044 return exit_status;
1045}
1046]])
55f48c48 1047AT_BISON_OPTION_POPDEFS
d659304d 1048
da730230 1049AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [],
d87ea54c
AD
1050[[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
1051glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1052]])
d659304d
JD
1053AT_COMPILE([glr-regr12])
1054
7d2d521f 1055AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
d659304d
JD
1056
1057AT_CLEANUP
bf70fa87
JD
1058
1059
1060## ------------------------------------------------------------------------- ##
1061## Incorrect lookahead during deterministic GLR. See ##
3f001415
JD
1062## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1063## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
bf70fa87
JD
1064## ------------------------------------------------------------------------- ##
1065
1066AT_SETUP([Incorrect lookahead during deterministic GLR])
1067
55f48c48 1068AT_BISON_OPTION_PUSHDEFS
bf70fa87
JD
1069AT_DATA_GRAMMAR([glr-regr13.y],
1070[[
1071/* Tests:
1072 - Defaulted state with initial yychar: yychar == YYEMPTY.
1073 - Nondefaulted state: yychar != YYEMPTY.
1074 - Defaulted state after lookahead: yychar != YYEMPTY.
3f001415
JD
1075 - Defaulted state after shift: yychar == YYEMPTY.
1076 - User action changing the lookahead. */
bf70fa87
JD
1077
1078%{
1079 #include <stdio.h>
77519a7d 1080 #include <assert.h>
55f48c48
AD
1081 ]AT_YYERROR_DECLARE[
1082 ]AT_YYLEX_DECLARE[
742e4900 1083 static void print_lookahead (char const *);
bf70fa87
JD
1084 #define USE(value)
1085%}
1086
1087%union { char value; }
1088%type <value> 'a' 'b'
1089%glr-parser
1090%locations
1091
1092%%
1093
1094start:
3f001415 1095 defstate_init defstate_shift 'b' change_lookahead 'a' {
bf70fa87 1096 USE ($3);
742e4900 1097 print_lookahead ("start <- defstate_init defstate_shift 'b'");
bf70fa87
JD
1098 }
1099 ;
1100defstate_init:
1101 {
742e4900 1102 print_lookahead ("defstate_init <- empty string");
bf70fa87
JD
1103 }
1104 ;
1105defstate_shift:
1106 nondefstate defstate_look 'a' {
1107 USE ($3);
742e4900 1108 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
bf70fa87
JD
1109 }
1110 ;
1111defstate_look:
1112 {
742e4900 1113 print_lookahead ("defstate_look <- empty string");
bf70fa87
JD
1114 }
1115 ;
1116nondefstate:
1117 {
742e4900 1118 print_lookahead ("nondefstate <- empty string");
bf70fa87
JD
1119 }
1120 | 'b' {
1121 USE ($1);
742e4900 1122 print_lookahead ("nondefstate <- 'b'");
bf70fa87
JD
1123 }
1124 ;
3f001415
JD
1125change_lookahead:
1126 {
1127 yychar = 'a';
1128 }
1129 ;
bf70fa87
JD
1130
1131%%
1132
55f48c48 1133]AT_YYERROR_DEFINE[
087dcd78
AD
1134]AT_YYLEX_DEFINE(["ab"],
1135 [yylval.value = res + 'A' - 'a'])[
bf70fa87
JD
1136
1137static void
742e4900 1138print_lookahead (char const *reduction)
bf70fa87
JD
1139{
1140 printf ("%s:\n yychar=", reduction);
1141 if (yychar == YYEMPTY)
1142 printf ("YYEMPTY");
1143 else if (yychar == YYEOF)
1144 printf ("YYEOF");
1145 else
1146 {
1147 printf ("'%c', yylval='", yychar);
1148 if (yylval.value > ' ')
1149 printf ("%c", yylval.value);
1150 printf ("', yylloc=(%d,%d),(%d,%d)",
1151 yylloc.first_line, yylloc.first_column,
1152 yylloc.last_line, yylloc.last_column);
1153 }
1154 printf ("\n");
1155}
1156
1157int
1158main (void)
1159{
1160 yychar = '#'; /* Not a token in the grammar. */
1161 yylval.value = '!';
1162 return yyparse ();
1163}
1164]])
55f48c48 1165AT_BISON_OPTION_POPDEFS
bf70fa87 1166
da730230 1167AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], [])
bf70fa87
JD
1168AT_COMPILE([glr-regr13])
1169
7d2d521f 1170AT_PARSER_CHECK([[./glr-regr13]], 0,
bf70fa87
JD
1171[defstate_init <- empty string:
1172 yychar=YYEMPTY
1173nondefstate <- empty string:
1174 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1175defstate_look <- empty string:
1176 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1177defstate_shift <- nondefstate defstate_look 'a':
1178 yychar=YYEMPTY
1179start <- defstate_init defstate_shift 'b':
1180 yychar=YYEMPTY
1181], [])
1182
1183AT_CLEANUP
1184
1185
c8e966e2
AD
1186## ------------------------------------------------- ##
1187## Incorrect lookahead during nondeterministic GLR. ##
1188## ------------------------------------------------- ##
bf70fa87
JD
1189
1190AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1191
55f48c48 1192AT_BISON_OPTION_PUSHDEFS
bf70fa87
JD
1193AT_DATA_GRAMMAR([glr-regr14.y],
1194[[
1195/* Tests:
b7691f15 1196 - Conflicting actions (split-off parse, which copies lookahead need,
bf70fa87
JD
1197 which is necessarily yytrue) and nonconflicting actions (non-split-off
1198 parse) for nondefaulted state: yychar != YYEMPTY.
b7691f15 1199 - Merged deferred actions (lookahead need and RHS from different stack
bf70fa87
JD
1200 than the target state) and nonmerged deferred actions (same stack).
1201 - Defaulted state after lookahead: yychar != YYEMPTY.
1202 - Defaulted state after shift: yychar == YYEMPTY.
b7691f15 1203 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
bf70fa87
JD
1204 seen the lookahead but current stack has not).
1205 - Exceeding stack capacity (stack explosion), and thus reallocating
b7691f15 1206 lookahead need array.
bf70fa87
JD
1207 Note that it does not seem possible to see the initial yychar value during
1208 nondeterministic operation since:
1209 - In order to preserve the initial yychar, only defaulted states may be
1210 entered.
1211 - If only defaulted states are entered, there are no conflicts, so
1212 nondeterministic operation does not start. */
1213
1214%union { char value; }
1215
1216%{
cf806753 1217 #include <stdlib.h>
bf70fa87 1218 #include <stdio.h>
77519a7d 1219 #include <assert.h>
55f48c48
AD
1220 ]AT_YYERROR_DECLARE[
1221 ]AT_YYLEX_DECLARE[
742e4900 1222 static void print_lookahead (char const *);
bf70fa87
JD
1223 static char merge (union YYSTYPE, union YYSTYPE);
1224 #define USE(value)
1225%}
1226
1227%type <value> 'a' 'b' 'c' 'd' stack_explosion
1228%glr-parser
1229%locations
1230
1231%%
1232
1233start:
1234 merge 'c' stack_explosion {
1235 USE ($2); USE ($3);
742e4900 1236 print_lookahead ("start <- merge 'c' stack_explosion");
bf70fa87
JD
1237 }
1238 ;
1239
b7691f15 1240/* When merging the 2 deferred actions, the lookahead needs are different. */
bf70fa87
JD
1241merge:
1242 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1243 USE ($2); USE ($3);
742e4900 1244 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
bf70fa87
JD
1245 }
1246 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1247 USE ($3); USE ($5);
742e4900 1248 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
bf70fa87
JD
1249 " defstate_shift");
1250 }
1251 ;
1252
1253nonconflict1:
1254 {
742e4900 1255 print_lookahead ("nonconflict1 <- empty string");
bf70fa87
JD
1256 }
1257 ;
1258nonconflict2:
1259 {
742e4900 1260 print_lookahead ("nonconflict2 <- empty string");
bf70fa87
JD
1261 }
1262 | 'a' {
1263 USE ($1);
742e4900 1264 print_lookahead ("nonconflict2 <- 'a'");
bf70fa87
JD
1265 }
1266 ;
1267conflict:
1268 {
742e4900 1269 print_lookahead ("conflict <- empty string");
bf70fa87
JD
1270 }
1271 ;
1272defstate_look:
1273 {
742e4900 1274 print_lookahead ("defstate_look <- empty string");
bf70fa87
JD
1275 }
1276 ;
1277
b7691f15 1278/* yychar != YYEMPTY but lookahead need is yyfalse. */
bf70fa87
JD
1279defstate_shift:
1280 {
742e4900 1281 print_lookahead ("defstate_shift <- empty string");
bf70fa87
JD
1282 }
1283 ;
1284
1285stack_explosion:
1286 { $$ = '\0'; }
1287 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1288 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1289 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1290 ;
1291alt1:
1292 'd' no_look {
1293 USE ($1);
1294 if (yychar != 'd' && yychar != YYEOF)
1295 {
1296 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1297 }
1298 }
1299 ;
1300alt2:
1301 'd' no_look {
1302 USE ($1);
1303 if (yychar != 'd' && yychar != YYEOF)
1304 {
1305 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1306 }
1307 }
1308 ;
1309alt3:
1310 'd' no_look {
1311 USE ($1);
1312 if (yychar != 'd' && yychar != YYEOF)
1313 {
1314 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1315 }
1316 }
1317 ;
1318no_look:
1319 {
1320 if (yychar != YYEMPTY)
1321 {
1322 fprintf (stderr,
1323 "Found lookahead where shouldn't during stack explosion.\n");
1324 }
1325 }
1326 ;
1327
1328%%
1329
55f48c48 1330]AT_YYERROR_DEFINE[
bf70fa87
JD
1331static int
1332yylex (void)
1333{
cf806753
PE
1334 static char const input[] = "abcdddd";
1335 static size_t toknum;
77519a7d 1336 assert (toknum < sizeof input);
bf70fa87 1337 yylloc.first_line = yylloc.last_line = 1;
cf806753
PE
1338 yylloc.first_column = yylloc.last_column = toknum + 1;
1339 yylval.value = input[toknum] + 'A' - 'a';
1340 return input[toknum++];
bf70fa87
JD
1341}
1342
1343static void
742e4900 1344print_lookahead (char const *reduction)
bf70fa87
JD
1345{
1346 printf ("%s:\n yychar=", reduction);
1347 if (yychar == YYEMPTY)
1348 printf ("YYEMPTY");
1349 else if (yychar == YYEOF)
1350 printf ("YYEOF");
1351 else
1352 {
1353 printf ("'%c', yylval='", yychar);
1354 if (yylval.value > ' ')
1355 printf ("%c", yylval.value);
1356 printf ("', yylloc=(%d,%d),(%d,%d)",
1357 yylloc.first_line, yylloc.first_column,
1358 yylloc.last_line, yylloc.last_column);
1359 }
1360 printf ("\n");
1361}
1362
1363static char
1364merge (union YYSTYPE s1, union YYSTYPE s2)
1365{
1366 char dummy = s1.value + s2.value;
1367 return dummy;
1368}
1369
1370int
1371main (void)
1372{
1373 yychar = '#'; /* Not a token in the grammar. */
1374 yylval.value = '!';
1375 return yyparse ();
1376}
1377]])
55f48c48 1378AT_BISON_OPTION_POPDEFS
bf70fa87 1379
da730230 1380AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
d87ea54c
AD
1381[[glr-regr14.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1382]])
bf70fa87
JD
1383AT_COMPILE([glr-regr14])
1384
7d2d521f 1385AT_PARSER_CHECK([[./glr-regr14]], 0,
bf70fa87
JD
1386[conflict <- empty string:
1387 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1388defstate_look <- empty string:
1389 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1390nonconflict2 <- empty string:
1391 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1392defstate_shift <- empty string:
1393 yychar=YYEMPTY
1394merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1395 yychar=YYEMPTY
1396start <- merge 'c' stack_explosion:
1397 yychar=YYEOF
1398], [])
1399
1400AT_CLEANUP
35ee866a
JD
1401
1402
c8e966e2
AD
1403## ------------------------------------------------- ##
1404## Leaked semantic values when reporting ambiguity. ##
1405## ------------------------------------------------- ##
35ee866a
JD
1406
1407AT_SETUP([Leaked semantic values when reporting ambiguity])
1408
55f48c48 1409AT_BISON_OPTION_PUSHDEFS
35ee866a
JD
1410AT_DATA_GRAMMAR([glr-regr15.y],
1411[[
1412%glr-parser
35ee866a
JD
1413%destructor { parent_rhs_before_value = 0; } parent_rhs_before
1414
1415%{
1416# include <stdlib.h>
55f48c48
AD
1417 ]AT_YYERROR_DECLARE[
1418 ]AT_YYLEX_DECLARE[
35ee866a
JD
1419 static int parent_rhs_before_value = 0;
1420# define USE(val)
1421%}
1422
1423%%
1424
1425start:
1426 alt1 %dprec 1
1427 | alt2 %dprec 2
1428 ;
1429
1430/* This stack must be merged into the other stacks *last* (added at the
1431 beginning of the semantic options list) so that yyparse will choose to clean
1432 it up rather than the tree for which some semantic actions have been
1433 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1434 those other trees are not cleaned up. */
1435alt1: ;
1436
1437alt2:
1438 parent_rhs_before ambiguity {
1439 USE ($1);
1440 parent_rhs_before_value = 0;
1441 }
1442 ;
1443
1444parent_rhs_before:
1445 {
1446 USE ($$);
1447 parent_rhs_before_value = 1;
1448 }
1449 ;
1450
1451ambiguity: ambiguity1 | ambiguity2 ;
1452ambiguity1: ;
1453ambiguity2: ;
1454
1455%%
55f48c48 1456]AT_YYERROR_DEFINE[
95361618 1457]AT_YYLEX_DEFINE[
35ee866a
JD
1458
1459int
1460main (void)
1461{
1462 int exit_status = yyparse () != 1;
1463 if (parent_rhs_before_value)
1464 {
1465 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1466 exit_status = 1;
1467 }
1468 return exit_status;
1469}
1470]])
55f48c48 1471AT_BISON_OPTION_POPDEFS
35ee866a 1472
da730230 1473AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
d87ea54c
AD
1474[[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
1475]])
35ee866a
JD
1476AT_COMPILE([glr-regr15])
1477
7d2d521f 1478AT_PARSER_CHECK([[./glr-regr15]], 0, [],
35ee866a
JD
1479[syntax is ambiguous
1480])
1481
1482AT_CLEANUP
ae952af2
JD
1483
1484
c8e966e2
AD
1485## ------------------------------------------------------------ ##
1486## Leaked lookahead after nondeterministic parse syntax error. ##
1487## ------------------------------------------------------------ ##
ae952af2
JD
1488
1489AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
55f48c48
AD
1490
1491AT_BISON_OPTION_PUSHDEFS
ae952af2
JD
1492AT_DATA_GRAMMAR([glr-regr16.y],
1493[[
1494%glr-parser
1495%destructor { lookahead_value = 0; } 'b'
1496
1497%{
1498# include <stdlib.h>
77519a7d 1499# include <assert.h>
55f48c48
AD
1500 ]AT_YYERROR_DECLARE[
1501 ]AT_YYLEX_DECLARE[
ae952af2
JD
1502 static int lookahead_value = 0;
1503# define USE(val)
1504%}
1505
1506%%
1507
1508start: alt1 'a' | alt2 'a' ;
1509alt1: ;
1510alt2: ;
1511
1512%%
1513
55f48c48 1514]AT_YYERROR_DEFINE[
087dcd78
AD
1515]AT_YYLEX_DEFINE(["ab"],
1516 [if (res == 'b')
1517 lookahead_value = 1])[
ae952af2
JD
1518
1519int
1520main (void)
1521{
1522 int exit_status = yyparse () != 1;
1523 if (lookahead_value)
1524 {
1525 fprintf (stderr, "Lookahead destructor not called.\n");
1526 exit_status = 1;
1527 }
1528 return exit_status;
1529}
1530]])
55f48c48 1531AT_BISON_OPTION_POPDEFS
ae952af2 1532
da730230 1533AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
d87ea54c
AD
1534[[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1535]])
ae952af2
JD
1536AT_COMPILE([glr-regr16])
1537
7d2d521f 1538AT_PARSER_CHECK([[./glr-regr16]], 0, [],
ae952af2
JD
1539[syntax error
1540])
1541
1542AT_CLEANUP
8710fc41
JD
1543
1544
c8e966e2
AD
1545## ------------------------------------------------- ##
1546## Uninitialized location when reporting ambiguity. ##
1547## ------------------------------------------------- ##
8710fc41
JD
1548
1549AT_SETUP([Uninitialized location when reporting ambiguity])
55f48c48 1550
8d6c1b5e
AD
1551AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations %define api.pure])
1552
8710fc41
JD
1553AT_DATA_GRAMMAR([glr-regr17.y],
1554[[
1555%glr-parser
1556%locations
d9df47b6 1557%define api.pure
8710fc41
JD
1558%error-verbose
1559
1560%union { int dummy; }
1561
1562%{
8d6c1b5e
AD
1563 ]AT_YYERROR_DECLARE[
1564 ]AT_YYLEX_DECLARE[
8710fc41
JD
1565%}
1566
8710fc41
JD
1567%%
1568
5ad0a449
JD
1569/* Tests the case of an empty RHS that has inherited the location of the
1570 previous nonterminal, which is unresolved. That location is reported as the
1571 last position of the ambiguity. */
1572start: ambig1 empty1 | ambig2 empty2 ;
1573
8710fc41 1574/* Tests multiple levels of yyresolveLocations recursion. */
8710fc41
JD
1575ambig1: sub_ambig1 | sub_ambig2 ;
1576ambig2: sub_ambig1 | sub_ambig2 ;
1577
5ad0a449
JD
1578/* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1579 has inherited the initial location. The empty RHS's location is reported as
1580 the first position in the ambiguity. */
1581sub_ambig1: empty1 'a' 'b' ;
1582sub_ambig2: empty2 'a' 'b' ;
1583empty1: ;
1584empty2: ;
8710fc41
JD
1585
1586%%
77519a7d 1587# include <assert.h>
8710fc41 1588
8d6c1b5e 1589]AT_YYERROR_DEFINE[
6d05403d 1590static int
8710fc41
JD
1591yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1592{
6d05403d 1593 static char const input[] = "ab";
cf806753 1594 static size_t toknum;
77519a7d 1595 assert (toknum < sizeof input);
6d05403d 1596 lvalp->dummy = 0;
8710fc41 1597 llocp->first_line = llocp->last_line = 2;
cf806753 1598 llocp->first_column = toknum + 1;
8710fc41 1599 llocp->last_column = llocp->first_column + 1;
cf806753 1600 return input[toknum++];
8710fc41
JD
1601}
1602
1603int
1604main (void)
1605{
1606 return yyparse () != 1;
1607}
1608]])
55f48c48 1609AT_BISON_OPTION_POPDEFS
8710fc41 1610
da730230 1611AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [],
d87ea54c
AD
1612[[glr-regr17.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1613]])
8710fc41
JD
1614AT_COMPILE([glr-regr17])
1615
7d2d521f 1616AT_PARSER_CHECK([[./glr-regr17]], 0, [],
8d6c1b5e 1617[1.1-2.2: syntax is ambiguous
8710fc41
JD
1618])
1619
1620AT_CLEANUP
8ee5b538
JD
1621
1622
c8e966e2
AD
1623## ------------------------------------------------------------- ##
1624## Missed %merge type warnings when LHS type is declared later. ##
1625## ------------------------------------------------------------- ##
8ee5b538
JD
1626
1627AT_SETUP([Missed %merge type warnings when LHS type is declared later])
55f48c48
AD
1628
1629AT_BISON_OPTION_PUSHDEFS
8ee5b538
JD
1630AT_DATA_GRAMMAR([glr-regr18.y],
1631[[%glr-parser
1632
1633%{
cf806753 1634 #include <stdlib.h>
55f48c48 1635 ]AT_YYERROR_DECLARE[
290a8ff2 1636 ]AT_YYLEX_DECLARE[
8ee5b538
JD
1637%}
1638
1639%union {
1640 int type1;
1641 int type2;
dd60572a 1642 int type3;
8ee5b538
JD
1643}
1644
1645%%
1646
1647sym1: sym2 %merge<merge> { $$ = $1; } ;
dd60572a
JD
1648sym2: sym3 %merge<merge> { $$ = $1; } ;
1649sym3: %merge<merge> { $$ = 0; } ;
8ee5b538
JD
1650
1651%type <type1> sym1;
1652%type <type2> sym2;
dd60572a 1653%type <type3> sym3;
8ee5b538
JD
1654
1655%%
55f48c48 1656]AT_YYERROR_DEFINE[
95361618 1657]AT_YYLEX_DEFINE[
8ee5b538
JD
1658int
1659main (void)
1660{
1661 return yyparse ();
1662}
1663]])
55f48c48 1664AT_BISON_OPTION_POPDEFS
8ee5b538 1665
da730230 1666AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
11b19212 1667[[glr-regr18.y:26.18-24: error: result type clash on merge function 'merge': <type2> != <type1>
24d96dd3 1668glr-regr18.y:25.18-24: previous declaration
b8e7ad58 1669glr-regr18.y:27.13-19: error: result type clash on merge function 'merge': <type3> != <type2>
24d96dd3 1670glr-regr18.y:26.18-24: previous declaration
11b19212 1671]])
8ee5b538
JD
1672
1673AT_CLEANUP
71cbc1ac
AD
1674
1675
1676## ------------------- ##
1677## Ambiguity reports. ##
1678## ------------------- ##
1679
1680AT_SETUP([Ambiguity reports])
1681
55f48c48 1682AT_BISON_OPTION_PUSHDEFS
71cbc1ac
AD
1683AT_DATA_GRAMMAR([input.y],
1684[[
1685%{
1686 #include <stdio.h>
1687 #include <stdlib.h>
55f48c48
AD
1688 ]AT_YYERROR_DECLARE[
1689 ]AT_YYLEX_DECLARE[
71cbc1ac
AD
1690%}
1691
1692%debug
1693%glr-parser
1694
1695%%
1696start:
1697 'a' b 'c' d
1698| 'a' b 'c' d
1699;
1700b: 'b';
1701d: /* nada. */;
1702%%
95361618 1703]AT_YYLEX_DEFINE(["abc"])[
55f48c48 1704]AT_YYERROR_DEFINE[
71cbc1ac
AD
1705int
1706main (void)
1707{
1708 yydebug = 1;
1709 return !!yyparse ();
1710}
1711]])
55f48c48 1712AT_BISON_OPTION_POPDEFS
71cbc1ac
AD
1713
1714AT_BISON_CHECK([[-o input.c input.y]], 0, [],
d87ea54c
AD
1715[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1716]])
71cbc1ac
AD
1717AT_COMPILE([input])
1718
1719AT_PARSER_CHECK([[./input]], 1, [],
1720[Starting parse
1721Entering state 0
1722Reading a token: Next token is token 'a' ()
1723Shifting token 'a' ()
1724Entering state 1
1725Reading a token: Next token is token 'b' ()
1726Shifting token 'b' ()
1727Entering state 3
1728Reducing stack 0 by rule 3 (line 25):
1729 $1 = token 'b' ()
1730-> $$ = nterm b ()
1731Entering state 4
1732Reading a token: Next token is token 'c' ()
1733Shifting token 'c' ()
1734Entering state 6
1735Reducing stack 0 by rule 4 (line 26):
1736-> $$ = nterm d ()
1737Entering state 7
1738Reading a token: Now at end of input.
1739Stack 0 Entering state 7
1740Now at end of input.
1741Splitting off stack 1 from 0.
1742Reduced stack 1 by rule #2; action deferred. Now in state 2.
1743Stack 1 Entering state 2
1744Now at end of input.
1745Reduced stack 0 by rule #1; action deferred. Now in state 2.
1746Merging stack 0 into stack 1.
1747Stack 1 Entering state 2
1748Now at end of input.
1749Removing dead stacks.
1750Rename stack 1 -> 0.
1751On stack 0, shifting token $end ()
1752Stack 0 now in state #5
1753Ambiguity detected.
1754Option 1,
1755 start -> <Rule 1, tokens 1 .. 3>
1756 'a' <tokens 1 .. 1>
1757 b <tokens 2 .. 2>
1758 'c' <tokens 3 .. 3>
1759 d <empty>
1760
1761Option 2,
1762 start -> <Rule 2, tokens 1 .. 3>
1763 'a' <tokens 1 .. 1>
1764 b <tokens 2 .. 2>
1765 'c' <tokens 3 .. 3>
1766 d <empty>
1767
1768syntax is ambiguous
1769Cleanup: popping token $end ()
1770Cleanup: popping unresolved nterm start ()
1771Cleanup: popping nterm d ()
1772Cleanup: popping token 'c' ()
1773Cleanup: popping nterm b ()
1774Cleanup: popping token 'a' ()
1775])
1776
1777AT_CLEANUP