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