]> git.saurik.com Git - bison.git/blob - tests/glr-regression.at
support $<tag>$ in printers and destructors
[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 ]AT_YYLEX_DEFINE([{ PARENT_RHS_AFTER, 0 }],
1002 [if (res == PARENT_RHS_AFTER)
1003 parent_rhs_after_value = 1;])[
1004
1005 int
1006 main (void)
1007 {
1008 int exit_status = yyparse ();
1009 if (parent_rhs_before_value)
1010 {
1011 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1012 exit_status = 1;
1013 }
1014 if (merged_value)
1015 {
1016 fprintf (stderr, "`merged' destructor not called.\n");
1017 exit_status = 1;
1018 }
1019 if (parent_rhs_after_value)
1020 {
1021 fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
1022 exit_status = 1;
1023 }
1024 return exit_status;
1025 }
1026 ]])
1027 AT_BISON_OPTION_POPDEFS
1028
1029 AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [],
1030 [glr-regr12.y: conflicts: 1 shift/reduce, 1 reduce/reduce
1031 ])
1032 AT_COMPILE([glr-regr12])
1033
1034 AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
1035
1036 AT_CLEANUP
1037
1038
1039 ## ------------------------------------------------------------------------- ##
1040 ## Incorrect lookahead during deterministic GLR. See ##
1041 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1042 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
1043 ## ------------------------------------------------------------------------- ##
1044
1045 AT_SETUP([Incorrect lookahead during deterministic GLR])
1046
1047 AT_BISON_OPTION_PUSHDEFS
1048 AT_DATA_GRAMMAR([glr-regr13.y],
1049 [[
1050 /* Tests:
1051 - Defaulted state with initial yychar: yychar == YYEMPTY.
1052 - Nondefaulted state: yychar != YYEMPTY.
1053 - Defaulted state after lookahead: yychar != YYEMPTY.
1054 - Defaulted state after shift: yychar == YYEMPTY.
1055 - User action changing the lookahead. */
1056
1057 %{
1058 #include <stdio.h>
1059 #include <assert.h>
1060 ]AT_YYERROR_DECLARE[
1061 ]AT_YYLEX_DECLARE[
1062 static void print_lookahead (char const *);
1063 #define USE(value)
1064 %}
1065
1066 %union { char value; }
1067 %type <value> 'a' 'b'
1068 %glr-parser
1069 %locations
1070
1071 %%
1072
1073 start:
1074 defstate_init defstate_shift 'b' change_lookahead 'a' {
1075 USE ($3);
1076 print_lookahead ("start <- defstate_init defstate_shift 'b'");
1077 }
1078 ;
1079 defstate_init:
1080 {
1081 print_lookahead ("defstate_init <- empty string");
1082 }
1083 ;
1084 defstate_shift:
1085 nondefstate defstate_look 'a' {
1086 USE ($3);
1087 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
1088 }
1089 ;
1090 defstate_look:
1091 {
1092 print_lookahead ("defstate_look <- empty string");
1093 }
1094 ;
1095 nondefstate:
1096 {
1097 print_lookahead ("nondefstate <- empty string");
1098 }
1099 | 'b' {
1100 USE ($1);
1101 print_lookahead ("nondefstate <- 'b'");
1102 }
1103 ;
1104 change_lookahead:
1105 {
1106 yychar = 'a';
1107 }
1108 ;
1109
1110 %%
1111
1112 ]AT_YYERROR_DEFINE[
1113 ]AT_YYLEX_DEFINE(["ab"],
1114 [yylval.value = res + 'A' - 'a'])[
1115
1116 static void
1117 print_lookahead (char const *reduction)
1118 {
1119 printf ("%s:\n yychar=", reduction);
1120 if (yychar == YYEMPTY)
1121 printf ("YYEMPTY");
1122 else if (yychar == YYEOF)
1123 printf ("YYEOF");
1124 else
1125 {
1126 printf ("'%c', yylval='", yychar);
1127 if (yylval.value > ' ')
1128 printf ("%c", yylval.value);
1129 printf ("', yylloc=(%d,%d),(%d,%d)",
1130 yylloc.first_line, yylloc.first_column,
1131 yylloc.last_line, yylloc.last_column);
1132 }
1133 printf ("\n");
1134 }
1135
1136 int
1137 main (void)
1138 {
1139 yychar = '#'; /* Not a token in the grammar. */
1140 yylval.value = '!';
1141 return yyparse ();
1142 }
1143 ]])
1144 AT_BISON_OPTION_POPDEFS
1145
1146 AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], [])
1147 AT_COMPILE([glr-regr13])
1148
1149 AT_PARSER_CHECK([[./glr-regr13]], 0,
1150 [defstate_init <- empty string:
1151 yychar=YYEMPTY
1152 nondefstate <- empty string:
1153 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1154 defstate_look <- empty string:
1155 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1156 defstate_shift <- nondefstate defstate_look 'a':
1157 yychar=YYEMPTY
1158 start <- defstate_init defstate_shift 'b':
1159 yychar=YYEMPTY
1160 ], [])
1161
1162 AT_CLEANUP
1163
1164
1165 ## ------------------------------------------------------------------------- ##
1166 ## Incorrect lookahead during nondeterministic GLR. ##
1167 ## ------------------------------------------------------------------------- ##
1168
1169 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1170
1171 AT_BISON_OPTION_PUSHDEFS
1172 AT_DATA_GRAMMAR([glr-regr14.y],
1173 [[
1174 /* Tests:
1175 - Conflicting actions (split-off parse, which copies lookahead need,
1176 which is necessarily yytrue) and nonconflicting actions (non-split-off
1177 parse) for nondefaulted state: yychar != YYEMPTY.
1178 - Merged deferred actions (lookahead need and RHS from different stack
1179 than the target state) and nonmerged deferred actions (same stack).
1180 - Defaulted state after lookahead: yychar != YYEMPTY.
1181 - Defaulted state after shift: yychar == YYEMPTY.
1182 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1183 seen the lookahead but current stack has not).
1184 - Exceeding stack capacity (stack explosion), and thus reallocating
1185 lookahead need array.
1186 Note that it does not seem possible to see the initial yychar value during
1187 nondeterministic operation since:
1188 - In order to preserve the initial yychar, only defaulted states may be
1189 entered.
1190 - If only defaulted states are entered, there are no conflicts, so
1191 nondeterministic operation does not start. */
1192
1193 %union { char value; }
1194
1195 %{
1196 #include <stdlib.h>
1197 #include <stdio.h>
1198 #include <assert.h>
1199 ]AT_YYERROR_DECLARE[
1200 ]AT_YYLEX_DECLARE[
1201 static void print_lookahead (char const *);
1202 static char merge (union YYSTYPE, union YYSTYPE);
1203 #define USE(value)
1204 %}
1205
1206 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1207 %glr-parser
1208 %locations
1209
1210 %%
1211
1212 start:
1213 merge 'c' stack_explosion {
1214 USE ($2); USE ($3);
1215 print_lookahead ("start <- merge 'c' stack_explosion");
1216 }
1217 ;
1218
1219 /* When merging the 2 deferred actions, the lookahead needs are different. */
1220 merge:
1221 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1222 USE ($2); USE ($3);
1223 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
1224 }
1225 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1226 USE ($3); USE ($5);
1227 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1228 " defstate_shift");
1229 }
1230 ;
1231
1232 nonconflict1:
1233 {
1234 print_lookahead ("nonconflict1 <- empty string");
1235 }
1236 ;
1237 nonconflict2:
1238 {
1239 print_lookahead ("nonconflict2 <- empty string");
1240 }
1241 | 'a' {
1242 USE ($1);
1243 print_lookahead ("nonconflict2 <- 'a'");
1244 }
1245 ;
1246 conflict:
1247 {
1248 print_lookahead ("conflict <- empty string");
1249 }
1250 ;
1251 defstate_look:
1252 {
1253 print_lookahead ("defstate_look <- empty string");
1254 }
1255 ;
1256
1257 /* yychar != YYEMPTY but lookahead need is yyfalse. */
1258 defstate_shift:
1259 {
1260 print_lookahead ("defstate_shift <- empty string");
1261 }
1262 ;
1263
1264 stack_explosion:
1265 { $$ = '\0'; }
1266 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1267 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1268 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1269 ;
1270 alt1:
1271 'd' no_look {
1272 USE ($1);
1273 if (yychar != 'd' && yychar != YYEOF)
1274 {
1275 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1276 }
1277 }
1278 ;
1279 alt2:
1280 'd' no_look {
1281 USE ($1);
1282 if (yychar != 'd' && yychar != YYEOF)
1283 {
1284 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1285 }
1286 }
1287 ;
1288 alt3:
1289 'd' no_look {
1290 USE ($1);
1291 if (yychar != 'd' && yychar != YYEOF)
1292 {
1293 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1294 }
1295 }
1296 ;
1297 no_look:
1298 {
1299 if (yychar != YYEMPTY)
1300 {
1301 fprintf (stderr,
1302 "Found lookahead where shouldn't during stack explosion.\n");
1303 }
1304 }
1305 ;
1306
1307 %%
1308
1309 ]AT_YYERROR_DEFINE[
1310 static int
1311 yylex (void)
1312 {
1313 static char const input[] = "abcdddd";
1314 static size_t toknum;
1315 assert (toknum < sizeof input);
1316 yylloc.first_line = yylloc.last_line = 1;
1317 yylloc.first_column = yylloc.last_column = toknum + 1;
1318 yylval.value = input[toknum] + 'A' - 'a';
1319 return input[toknum++];
1320 }
1321
1322 static void
1323 print_lookahead (char const *reduction)
1324 {
1325 printf ("%s:\n yychar=", reduction);
1326 if (yychar == YYEMPTY)
1327 printf ("YYEMPTY");
1328 else if (yychar == YYEOF)
1329 printf ("YYEOF");
1330 else
1331 {
1332 printf ("'%c', yylval='", yychar);
1333 if (yylval.value > ' ')
1334 printf ("%c", yylval.value);
1335 printf ("', yylloc=(%d,%d),(%d,%d)",
1336 yylloc.first_line, yylloc.first_column,
1337 yylloc.last_line, yylloc.last_column);
1338 }
1339 printf ("\n");
1340 }
1341
1342 static char
1343 merge (union YYSTYPE s1, union YYSTYPE s2)
1344 {
1345 char dummy = s1.value + s2.value;
1346 return dummy;
1347 }
1348
1349 int
1350 main (void)
1351 {
1352 yychar = '#'; /* Not a token in the grammar. */
1353 yylval.value = '!';
1354 return yyparse ();
1355 }
1356 ]])
1357 AT_BISON_OPTION_POPDEFS
1358
1359 AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
1360 [glr-regr14.y: conflicts: 3 reduce/reduce
1361 ])
1362 AT_COMPILE([glr-regr14])
1363
1364 AT_PARSER_CHECK([[./glr-regr14]], 0,
1365 [conflict <- empty string:
1366 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1367 defstate_look <- empty string:
1368 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1369 nonconflict2 <- empty string:
1370 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1371 defstate_shift <- empty string:
1372 yychar=YYEMPTY
1373 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1374 yychar=YYEMPTY
1375 start <- merge 'c' stack_explosion:
1376 yychar=YYEOF
1377 ], [])
1378
1379 AT_CLEANUP
1380
1381
1382 ## ------------------------------------------------------------------------- ##
1383 ## Leaked semantic values when reporting ambiguity. ##
1384 ## ------------------------------------------------------------------------- ##
1385
1386 AT_SETUP([Leaked semantic values when reporting ambiguity])
1387
1388 AT_BISON_OPTION_PUSHDEFS
1389 AT_DATA_GRAMMAR([glr-regr15.y],
1390 [[
1391 %glr-parser
1392 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1393
1394 %{
1395 # include <stdlib.h>
1396 ]AT_YYERROR_DECLARE[
1397 ]AT_YYLEX_DECLARE[
1398 static int parent_rhs_before_value = 0;
1399 # define USE(val)
1400 %}
1401
1402 %%
1403
1404 start:
1405 alt1 %dprec 1
1406 | alt2 %dprec 2
1407 ;
1408
1409 /* This stack must be merged into the other stacks *last* (added at the
1410 beginning of the semantic options list) so that yyparse will choose to clean
1411 it up rather than the tree for which some semantic actions have been
1412 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1413 those other trees are not cleaned up. */
1414 alt1: ;
1415
1416 alt2:
1417 parent_rhs_before ambiguity {
1418 USE ($1);
1419 parent_rhs_before_value = 0;
1420 }
1421 ;
1422
1423 parent_rhs_before:
1424 {
1425 USE ($$);
1426 parent_rhs_before_value = 1;
1427 }
1428 ;
1429
1430 ambiguity: ambiguity1 | ambiguity2 ;
1431 ambiguity1: ;
1432 ambiguity2: ;
1433
1434 %%
1435 ]AT_YYERROR_DEFINE[
1436 ]AT_YYLEX_DEFINE[
1437
1438 int
1439 main (void)
1440 {
1441 int exit_status = yyparse () != 1;
1442 if (parent_rhs_before_value)
1443 {
1444 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1445 exit_status = 1;
1446 }
1447 return exit_status;
1448 }
1449 ]])
1450 AT_BISON_OPTION_POPDEFS
1451
1452 AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
1453 [glr-regr15.y: conflicts: 2 reduce/reduce
1454 ])
1455 AT_COMPILE([glr-regr15])
1456
1457 AT_PARSER_CHECK([[./glr-regr15]], 0, [],
1458 [syntax is ambiguous
1459 ])
1460
1461 AT_CLEANUP
1462
1463
1464 ## ------------------------------------------------------------------------- ##
1465 ## Leaked lookahead after nondeterministic parse syntax error. ##
1466 ## ------------------------------------------------------------------------- ##
1467
1468 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1469
1470 AT_BISON_OPTION_PUSHDEFS
1471 AT_DATA_GRAMMAR([glr-regr16.y],
1472 [[
1473 %glr-parser
1474 %destructor { lookahead_value = 0; } 'b'
1475
1476 %{
1477 # include <stdlib.h>
1478 # include <assert.h>
1479 ]AT_YYERROR_DECLARE[
1480 ]AT_YYLEX_DECLARE[
1481 static int lookahead_value = 0;
1482 # define USE(val)
1483 %}
1484
1485 %%
1486
1487 start: alt1 'a' | alt2 'a' ;
1488 alt1: ;
1489 alt2: ;
1490
1491 %%
1492
1493 ]AT_YYERROR_DEFINE[
1494 ]AT_YYLEX_DEFINE(["ab"],
1495 [if (res == 'b')
1496 lookahead_value = 1])[
1497
1498 int
1499 main (void)
1500 {
1501 int exit_status = yyparse () != 1;
1502 if (lookahead_value)
1503 {
1504 fprintf (stderr, "Lookahead destructor not called.\n");
1505 exit_status = 1;
1506 }
1507 return exit_status;
1508 }
1509 ]])
1510 AT_BISON_OPTION_POPDEFS
1511
1512 AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
1513 [glr-regr16.y: conflicts: 1 reduce/reduce
1514 ])
1515 AT_COMPILE([glr-regr16])
1516
1517 AT_PARSER_CHECK([[./glr-regr16]], 0, [],
1518 [syntax error
1519 ])
1520
1521 AT_CLEANUP
1522
1523
1524 ## ------------------------------------------------------------------------- ##
1525 ## Uninitialized location when reporting ambiguity. ##
1526 ## ------------------------------------------------------------------------- ##
1527
1528 AT_SETUP([Uninitialized location when reporting ambiguity])
1529
1530 AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations %define api.pure])
1531
1532 AT_DATA_GRAMMAR([glr-regr17.y],
1533 [[
1534 %glr-parser
1535 %locations
1536 %define api.pure
1537 %error-verbose
1538
1539 %union { int dummy; }
1540
1541 %{
1542 ]AT_YYERROR_DECLARE[
1543 ]AT_YYLEX_DECLARE[
1544 %}
1545
1546 %initial-action {
1547 @$.first_line = 1;
1548 @$.first_column = 1;
1549 @$.last_line = 1;
1550 @$.last_column = 1;
1551 }
1552
1553 %%
1554
1555 /* Tests the case of an empty RHS that has inherited the location of the
1556 previous nonterminal, which is unresolved. That location is reported as the
1557 last position of the ambiguity. */
1558 start: ambig1 empty1 | ambig2 empty2 ;
1559
1560 /* Tests multiple levels of yyresolveLocations recursion. */
1561 ambig1: sub_ambig1 | sub_ambig2 ;
1562 ambig2: sub_ambig1 | sub_ambig2 ;
1563
1564 /* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1565 has inherited the initial location. The empty RHS's location is reported as
1566 the first position in the ambiguity. */
1567 sub_ambig1: empty1 'a' 'b' ;
1568 sub_ambig2: empty2 'a' 'b' ;
1569 empty1: ;
1570 empty2: ;
1571
1572 %%
1573 # include <assert.h>
1574
1575 ]AT_YYERROR_DEFINE[
1576 static int
1577 yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1578 {
1579 static char const input[] = "ab";
1580 static size_t toknum;
1581 assert (toknum < sizeof input);
1582 lvalp->dummy = 0;
1583 llocp->first_line = llocp->last_line = 2;
1584 llocp->first_column = toknum + 1;
1585 llocp->last_column = llocp->first_column + 1;
1586 return input[toknum++];
1587 }
1588
1589 int
1590 main (void)
1591 {
1592 return yyparse () != 1;
1593 }
1594 ]])
1595 AT_BISON_OPTION_POPDEFS
1596
1597 AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [],
1598 [glr-regr17.y: conflicts: 3 reduce/reduce
1599 ])
1600 AT_COMPILE([glr-regr17])
1601
1602 AT_PARSER_CHECK([[./glr-regr17]], 0, [],
1603 [1.1-2.2: syntax is ambiguous
1604 ])
1605
1606 AT_CLEANUP
1607
1608
1609 ## -------------------------------------------------------------##
1610 ## Missed %merge type warnings when LHS type is declared later. ##
1611 ## -------------------------------------------------------------##
1612
1613 AT_SETUP([Missed %merge type warnings when LHS type is declared later])
1614
1615 AT_BISON_OPTION_PUSHDEFS
1616 AT_DATA_GRAMMAR([glr-regr18.y],
1617 [[%glr-parser
1618
1619 %{
1620 #include <stdlib.h>
1621 ]AT_YYERROR_DECLARE[
1622 ]AT_YYLEX_DECLARE[
1623 %}
1624
1625 %union {
1626 int type1;
1627 int type2;
1628 int type3;
1629 }
1630
1631 %%
1632
1633 sym1: sym2 %merge<merge> { $$ = $1; } ;
1634 sym2: sym3 %merge<merge> { $$ = $1; } ;
1635 sym3: %merge<merge> { $$ = 0; } ;
1636
1637 %type <type1> sym1;
1638 %type <type2> sym2;
1639 %type <type3> sym3;
1640
1641 %%
1642 ]AT_YYERROR_DEFINE[
1643 ]AT_YYLEX_DEFINE[
1644 int
1645 main (void)
1646 {
1647 return yyparse ();
1648 }
1649 ]])
1650 AT_BISON_OPTION_POPDEFS
1651
1652 AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
1653 [glr-regr18.y:26.18-24: result type clash on merge function 'merge': <type2> != <type1>
1654 glr-regr18.y:25.18-24: previous declaration
1655 glr-regr18.y:27.13-19: result type clash on merge function 'merge': <type3> != <type2>
1656 glr-regr18.y:26.18-24: previous declaration
1657 ])
1658
1659 AT_CLEANUP
1660
1661
1662 ## ------------------- ##
1663 ## Ambiguity reports. ##
1664 ## ------------------- ##
1665
1666 AT_SETUP([Ambiguity reports])
1667
1668 AT_BISON_OPTION_PUSHDEFS
1669 AT_DATA_GRAMMAR([input.y],
1670 [[
1671 %{
1672 #include <stdio.h>
1673 #include <stdlib.h>
1674 ]AT_YYERROR_DECLARE[
1675 ]AT_YYLEX_DECLARE[
1676 %}
1677
1678 %debug
1679 %glr-parser
1680
1681 %%
1682 start:
1683 'a' b 'c' d
1684 | 'a' b 'c' d
1685 ;
1686 b: 'b';
1687 d: /* nada. */;
1688 %%
1689 ]AT_YYLEX_DEFINE(["abc"])[
1690 ]AT_YYERROR_DEFINE[
1691 int
1692 main (void)
1693 {
1694 yydebug = 1;
1695 return !!yyparse ();
1696 }
1697 ]])
1698 AT_BISON_OPTION_POPDEFS
1699
1700 AT_BISON_CHECK([[-o input.c input.y]], 0, [],
1701 [input.y: conflicts: 1 reduce/reduce
1702 ])
1703 AT_COMPILE([input])
1704
1705 AT_PARSER_CHECK([[./input]], 1, [],
1706 [Starting parse
1707 Entering state 0
1708 Reading a token: Next token is token 'a' ()
1709 Shifting token 'a' ()
1710 Entering state 1
1711 Reading a token: Next token is token 'b' ()
1712 Shifting token 'b' ()
1713 Entering state 3
1714 Reducing stack 0 by rule 3 (line 25):
1715 $1 = token 'b' ()
1716 -> $$ = nterm b ()
1717 Entering state 4
1718 Reading a token: Next token is token 'c' ()
1719 Shifting token 'c' ()
1720 Entering state 6
1721 Reducing stack 0 by rule 4 (line 26):
1722 -> $$ = nterm d ()
1723 Entering state 7
1724 Reading a token: Now at end of input.
1725 Stack 0 Entering state 7
1726 Now at end of input.
1727 Splitting off stack 1 from 0.
1728 Reduced stack 1 by rule #2; action deferred. Now in state 2.
1729 Stack 1 Entering state 2
1730 Now at end of input.
1731 Reduced stack 0 by rule #1; action deferred. Now in state 2.
1732 Merging stack 0 into stack 1.
1733 Stack 1 Entering state 2
1734 Now at end of input.
1735 Removing dead stacks.
1736 Rename stack 1 -> 0.
1737 On stack 0, shifting token $end ()
1738 Stack 0 now in state #5
1739 Ambiguity detected.
1740 Option 1,
1741 start -> <Rule 1, tokens 1 .. 3>
1742 'a' <tokens 1 .. 1>
1743 b <tokens 2 .. 2>
1744 'c' <tokens 3 .. 3>
1745 d <empty>
1746
1747 Option 2,
1748 start -> <Rule 2, tokens 1 .. 3>
1749 'a' <tokens 1 .. 1>
1750 b <tokens 2 .. 2>
1751 'c' <tokens 3 .. 3>
1752 d <empty>
1753
1754 syntax is ambiguous
1755 Cleanup: popping token $end ()
1756 Cleanup: popping unresolved nterm start ()
1757 Cleanup: popping nterm d ()
1758 Cleanup: popping token 'c' ()
1759 Cleanup: popping nterm b ()
1760 Cleanup: popping token 'a' ()
1761 ])
1762
1763 AT_CLEANUP