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