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