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