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