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