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