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