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