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