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