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