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