]> git.saurik.com Git - bison.git/blob - tests/glr-regression.at
Merge branch 'maint'
[bison.git] / tests / glr-regression.at
1 # Checking GLR Parsing: Regression Tests -*- Autotest -*-
2
3 # Copyright (C) 2002-2003, 2005-2007, 2009-2012 Free Software
4 # Foundation, Inc.
5
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19 AT_BANNER([[GLR Regression Tests]])
20
21 ## --------------------------- ##
22 ## Badly Collapsed GLR States. ##
23 ## --------------------------- ##
24
25 AT_SETUP([Badly Collapsed GLR States])
26
27 AT_BISON_OPTION_PUSHDEFS
28 AT_DATA_GRAMMAR([glr-regr1.y],
29 [[/* Regression Test: Improper state compression */
30 /* Reported by Scott McPeak */
31
32 %{
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <assert.h>
36
37 #define YYSTYPE int
38 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1);
39 ]AT_YYERROR_DECLARE[
40 ]AT_YYLEX_DECLARE[
41 %}
42
43
44 %glr-parser
45
46
47 /* -------- productions ------ */
48 %%
49
50 StartSymbol: E { $$=0; } %merge <exprMerge>
51 ;
52
53 E: E 'P' E { $$=1; printf("E -> E 'P' E\n"); } %merge <exprMerge>
54 | 'B' { $$=2; printf("E -> 'B'\n"); } %merge <exprMerge>
55 ;
56
57
58
59 /* ---------- C code ----------- */
60 %%
61
62 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1)
63 {
64 (void) x0;
65 (void) x1;
66 printf ("<OR>\n");
67 return 0;
68 }
69
70 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: warning: 1 shift/reduce conflict [-Wconflicts-sr]
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: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
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: warning: 1 shift/reduce conflict [-Wconflicts-sr]
329 glr-regr3.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
330 ]])
331 AT_COMPILE([glr-regr3])
332
333 AT_PARSER_CHECK([[echo p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2 | ./glr-regr3]],
334 0,
335 [[Result: 1c04
336 ]], [])
337
338 AT_CLEANUP
339
340
341 ## ------------------------------------------------------------------------- ##
342 ## Duplicate representation of merged trees. See ##
343 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>. ##
344 ## ------------------------------------------------------------------------- ##
345
346 AT_SETUP([Duplicate representation of merged trees])
347
348 AT_BISON_OPTION_PUSHDEFS
349 AT_DATA_GRAMMAR([glr-regr4.y],
350 [[
351 %union { char *ptr; }
352 %type <ptr> S A A1 A2 B
353 %glr-parser
354
355 %{
356 #include <stdio.h>
357 #include <stdlib.h>
358 #include <string.h>
359 static char *merge (YYSTYPE, YYSTYPE);
360 static char *make_value (char const *, char const *);
361 ]AT_YYERROR_DECLARE[
362 ]AT_YYLEX_DECLARE[
363 static char *ptrs[100];
364 static char **ptrs_next = ptrs;
365 %}
366
367 %%
368
369 tree: S { printf ("%s\n", $1); } ;
370
371 S:
372 A %merge<merge> { $$ = make_value ("S", $1); }
373 | B %merge<merge> { $$ = make_value ("S", $1); }
374 ;
375
376 A:
377 A1 %merge<merge> { $$ = make_value ("A", $1); }
378 | A2 %merge<merge> { $$ = make_value ("A", $1); }
379 ;
380
381 A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
382 A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
383 B: 'a' { $$ = make_value ("B", "'a'"); } ;
384
385 %%
386 ]AT_YYERROR_DEFINE[
387 ]AT_YYLEX_DEFINE(["a"])[
388
389 int
390 main (void)
391 {
392 int status = yyparse ();
393 while (ptrs_next != ptrs)
394 free (*--ptrs_next);
395 return status;
396 }
397
398 static char *
399 make_value (char const *parent, char const *child)
400 {
401 char const format[] = "%s <- %s";
402 char *value = *ptrs_next++ =
403 (char *) malloc (strlen (parent) + strlen (child) + sizeof format);
404 sprintf (value, format, parent, child);
405 return value;
406 }
407
408 static char *
409 merge (YYSTYPE s1, YYSTYPE s2)
410 {
411 char const format[] = "merge{ %s and %s }";
412 char *value = *ptrs_next++ =
413 (char *) malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format);
414 sprintf (value, format, s1.ptr, s2.ptr);
415 return value;
416 }
417 ]])
418 AT_BISON_OPTION_POPDEFS
419
420 AT_BISON_CHECK([[-o glr-regr4.c glr-regr4.y]], 0, [],
421 [[glr-regr4.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
422 ]])
423 AT_COMPILE([glr-regr4])
424
425 AT_PARSER_CHECK([[./glr-regr4]], 0,
426 [[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
427 ]], [])
428
429 AT_CLEANUP
430
431
432 ## -------------------------------------------------------------------------- ##
433 ## User destructor for unresolved GLR semantic value. See ##
434 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>. ##
435 ## -------------------------------------------------------------------------- ##
436
437 AT_SETUP([User destructor for unresolved GLR semantic value])
438
439 AT_BISON_OPTION_PUSHDEFS
440 AT_DATA_GRAMMAR([glr-regr5.y],
441 [[
442 %{
443 #include <stdio.h>
444 #include <stdlib.h>
445 ]AT_YYERROR_DECLARE[
446 ]AT_YYLEX_DECLARE[
447 enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
448 %}
449
450 %glr-parser
451 %union { int value; }
452 %type <value> start
453
454 %destructor {
455 if ($$ != MAGIC_VALUE)
456 {
457 fprintf (stderr, "Bad destructor call.\n");
458 exit (EXIT_FAILURE);
459 }
460 } start
461
462 %%
463
464 start:
465 'a' { $$ = MAGIC_VALUE; }
466 | 'a' { $$ = MAGIC_VALUE; }
467 ;
468
469 %%
470 ]AT_YYLEX_DEFINE(["a"])[
471 ]AT_YYERROR_DEFINE[
472 int
473 main (void)
474 {
475 return yyparse () != 1;
476 }
477 ]])
478 AT_BISON_OPTION_POPDEFS
479
480 AT_BISON_CHECK([[-o glr-regr5.c glr-regr5.y]], 0, [],
481 [[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
482 ]])
483 AT_COMPILE([glr-regr5])
484
485 AT_PARSER_CHECK([[./glr-regr5]], 0, [],
486 [syntax is ambiguous
487 ])
488
489 AT_CLEANUP
490
491
492 ## -------------------------------------------------------------------------- ##
493 ## User destructor after an error during a split parse. See ##
494 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>. ##
495 ## -------------------------------------------------------------------------- ##
496
497 AT_SETUP([User destructor after an error during a split parse])
498
499 AT_BISON_OPTION_PUSHDEFS
500 AT_DATA_GRAMMAR([glr-regr6.y],
501 [[
502 %{
503 #include <stdio.h>
504 #include <stdlib.h>
505 ]AT_YYERROR_DECLARE[
506 ]AT_YYLEX_DECLARE[
507 %}
508
509 %glr-parser
510 %union { int value; }
511 %type <value> 'a'
512
513 %destructor {
514 printf ("Destructor called.\n");
515 } 'a'
516
517 %%
518
519 start: 'a' | 'a' ;
520
521 %%
522 ]AT_YYERROR_DEFINE[
523 ]AT_YYLEX_DEFINE(["a"])[
524 int
525 main (void)
526 {
527 return yyparse () != 1;
528 }
529 ]])
530 AT_BISON_OPTION_POPDEFS
531
532 AT_BISON_CHECK([[-o glr-regr6.c glr-regr6.y]], 0, [],
533 [[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
534 ]])
535 AT_COMPILE([glr-regr6])
536
537 AT_PARSER_CHECK([[./glr-regr6]], 0,
538 [Destructor called.
539 ],
540 [syntax is ambiguous
541 ])
542
543 AT_CLEANUP
544
545
546 ## ------------------------------------------------------------------------- ##
547 ## Duplicated user destructor for lookahead. See ##
548 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>. ##
549 ## ------------------------------------------------------------------------- ##
550
551 AT_SETUP([Duplicated user destructor for lookahead])
552
553 AT_BISON_OPTION_PUSHDEFS
554 AT_DATA_GRAMMAR([glr-regr7.y],
555 [[
556 %{
557 #include <stdio.h>
558 #include <stdlib.h>
559 ]AT_YYERROR_DECLARE[
560 ]AT_YYLEX_DECLARE[
561 #define YYSTACKEXPANDABLE 0
562 typedef struct count_node {
563 int count;
564 struct count_node *prev;
565 } count_node;
566 static count_node *tail;
567 %}
568
569 %glr-parser
570 %union { count_node *node; }
571 %type <node> 'a'
572
573 %destructor {
574 if ($$->count++)
575 fprintf (stderr, "Destructor called on same value twice.\n");
576 } 'a'
577
578 %%
579
580 start:
581 stack1 start
582 | stack2 start
583 | /* empty */
584 ;
585 stack1: 'a' ;
586 stack2: 'a' ;
587
588 %%
589
590 static int
591 yylex (void)
592 {
593 yylval.node = (count_node*) malloc (sizeof *yylval.node);
594 if (!yylval.node)
595 {
596 fprintf (stderr, "Test inconclusive.\n");
597 exit (EXIT_FAILURE);
598 }
599 yylval.node->count = 0;
600 yylval.node->prev = tail;
601 tail = yylval.node;
602 return 'a';
603 }
604
605 ]AT_YYERROR_DEFINE[
606 int
607 main (void)
608 {
609 int status = yyparse ();
610 while (tail)
611 {
612 count_node *prev = tail->prev;
613 free (tail);
614 tail = prev;
615 }
616 return status;
617 }
618 ]])
619 AT_BISON_OPTION_POPDEFS
620
621 AT_BISON_CHECK([[-o glr-regr7.c glr-regr7.y]], 0, [],
622 [[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
623 ]])
624 AT_COMPILE([glr-regr7])
625
626 AT_PARSER_CHECK([[./glr-regr7]], 2, [],
627 [memory exhausted
628 ])
629
630 AT_CLEANUP
631
632
633 ## ------------------------------------------------------------------------- ##
634 ## Incorrect default location for empty right-hand sides. Adapted from bug ##
635 ## report by Claudia Hermann. ##
636 ## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
637 ## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html ##
638 ## ------------------------------------------------------------------------- ##
639
640 AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
641
642 AT_BISON_OPTION_PUSHDEFS
643 AT_DATA_GRAMMAR([glr-regr8.y],
644 [[
645 %{
646 #include <stdio.h>
647 #include <stdlib.h>
648 ]AT_YYERROR_DECLARE[
649 ]AT_YYLEX_DECLARE[
650 %}
651
652 %token T_CONSTANT
653 %token T_PORT
654 %token T_SIGNAL
655
656 %glr-parser
657
658 %%
659
660
661 PortClause : T_PORT InterfaceDeclaration T_PORT
662 { printf("%d/%d - %d/%d - %d/%d\n",
663 @1.first_column, @1.last_column,
664 @2.first_column, @2.last_column,
665 @3.first_column, @3.last_column); }
666 ;
667
668 InterfaceDeclaration : OptConstantWord %dprec 1
669 | OptSignalWord %dprec 2
670 ;
671
672 OptConstantWord : /* empty */
673 | T_CONSTANT
674 ;
675
676 OptSignalWord : /* empty */
677 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
678 | T_SIGNAL
679 ;
680
681 %%
682
683 ]AT_YYERROR_DEFINE[
684 static int lexIndex;
685
686 int yylex (void)
687 {
688 lexIndex += 1;
689 switch (lexIndex)
690 {
691 default:
692 abort ();
693 case 1:
694 yylloc.first_column = 1;
695 yylloc.last_column = 9;
696 return T_PORT;
697 case 2:
698 yylloc.first_column = 13;
699 yylloc.last_column = 17;
700 return T_PORT;
701 case 3:
702 return 0;
703 }
704 }
705
706 int
707 main (void)
708 {
709 yyparse();
710 return 0;
711 }
712 ]])
713 AT_BISON_OPTION_POPDEFS
714
715 AT_BISON_CHECK([[-o glr-regr8.c glr-regr8.y]], 0, [],
716 [[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
717 ]])
718 AT_COMPILE([glr-regr8])
719
720 AT_PARSER_CHECK([[./glr-regr8]], 0,
721 [empty: 9/9
722 1/9 - 9/9 - 13/17
723 ],
724 [])
725
726 AT_CLEANUP
727
728
729 ## ------------------------------------------------------------------------- ##
730 ## No users destructors if stack 0 deleted. See ##
731 ## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
732 ## ------------------------------------------------------------------------- ##
733
734 AT_SETUP([No users destructors if stack 0 deleted])
735
736 AT_BISON_OPTION_PUSHDEFS
737 AT_DATA_GRAMMAR([glr-regr9.y],
738 [[
739 %{
740 # include <stdio.h>
741 # include <stdlib.h>
742 ]AT_YYERROR_DECLARE[
743 ]AT_YYLEX_DECLARE[
744 # define YYSTACKEXPANDABLE 0
745 static int tokens = 0;
746 static int destructors = 0;
747 # define USE(Var)
748 %}
749
750 %glr-parser
751 %union { int dummy; }
752 %type <dummy> 'a'
753
754 %destructor {
755 destructors += 1;
756 } 'a'
757
758 %%
759
760 start:
761 ambig0 'a' { destructors += 2; USE ($2); }
762 | ambig1 start { destructors += 1; }
763 | ambig2 start { destructors += 1; }
764 ;
765
766 ambig0: 'a' ;
767 ambig1: 'a' ;
768 ambig2: 'a' ;
769
770 %%
771
772 static int
773 yylex (void)
774 {
775 tokens += 1;
776 return 'a';
777 }
778
779 ]AT_YYERROR_DEFINE[
780 int
781 main (void)
782 {
783 int exit_status;
784 exit_status = yyparse ();
785 if (tokens != destructors)
786 {
787 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
788 return 1;
789 }
790 return !exit_status;
791 }
792 ]])
793 AT_BISON_OPTION_POPDEFS
794
795 AT_BISON_CHECK([[-o glr-regr9.c glr-regr9.y]], 0, [],
796 [[glr-regr9.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
797 ]])
798 AT_COMPILE([glr-regr9])
799
800 AT_PARSER_CHECK([[./glr-regr9]], 0, [],
801 [memory exhausted
802 ])
803
804 AT_CLEANUP
805
806
807 ## ------------------------------------------------------------------------- ##
808 ## Corrupted semantic options if user action cuts parse. ##
809 ## ------------------------------------------------------------------------- ##
810
811 AT_SETUP([Corrupted semantic options if user action cuts parse])
812
813 AT_BISON_OPTION_PUSHDEFS
814 AT_DATA_GRAMMAR([glr-regr10.y],
815 [[
816 %{
817 # include <stdlib.h>
818 # include <stdio.h>
819 ]AT_YYERROR_DECLARE[
820 ]AT_YYLEX_DECLARE[
821 #define GARBAGE_SIZE 50
822 static char garbage[GARBAGE_SIZE];
823 %}
824
825 %glr-parser
826 %union { char *ptr; }
827 %type <ptr> start
828
829 %%
830
831 start:
832 %dprec 2 { $$ = garbage; YYACCEPT; }
833 | %dprec 1 { $$ = garbage; YYACCEPT; }
834 ;
835
836 %%
837 ]AT_YYERROR_DEFINE[
838 ]AT_YYLEX_DEFINE[
839
840 int
841 main (void)
842 {
843 int i;
844 for (i = 0; i < GARBAGE_SIZE; i+=1)
845 garbage[i] = 108;
846 return yyparse ();
847 }
848 ]])
849 AT_BISON_OPTION_POPDEFS
850
851 AT_BISON_CHECK([[-o glr-regr10.c glr-regr10.y]], 0, [],
852 [[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
853 ]])
854 AT_COMPILE([glr-regr10])
855
856 AT_PARSER_CHECK([[./glr-regr10]], 0, [], [])
857
858 AT_CLEANUP
859
860
861 ## ------------------------------------------------------------------------- ##
862 ## Undesirable destructors if user action cuts parse. ##
863 ## ------------------------------------------------------------------------- ##
864
865 AT_SETUP([Undesirable destructors if user action cuts parse])
866
867 AT_BISON_OPTION_PUSHDEFS
868 AT_DATA_GRAMMAR([glr-regr11.y],
869 [[
870 %{
871 # include <stdlib.h>
872 ]AT_YYERROR_DECLARE[
873 ]AT_YYLEX_DECLARE[
874 static int destructors = 0;
875 # define USE(val)
876 %}
877
878 %glr-parser
879 %union { int dummy; }
880 %type <int> 'a'
881 %destructor { destructors += 1; } 'a'
882
883 %%
884
885 start:
886 'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; }
887 | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; }
888 ;
889
890 %%
891
892 ]AT_YYERROR_DEFINE[
893 ]AT_YYLEX_DEFINE(["a"])[
894
895 int
896 main (void)
897 {
898 int exit_status = yyparse ();
899 if (destructors != 1)
900 {
901 fprintf (stderr, "Destructor calls: %d\n", destructors);
902 return 1;
903 }
904 return exit_status;
905 }
906 ]])
907 AT_BISON_OPTION_POPDEFS
908
909 AT_BISON_CHECK([[-o glr-regr11.c glr-regr11.y]], 0, [],
910 [[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
911 ]])
912 AT_COMPILE([glr-regr11])
913
914 AT_PARSER_CHECK([[./glr-regr11]], 0, [], [])
915
916 AT_CLEANUP
917
918
919 ## ------------------------------------------------------------------------- ##
920 ## Leaked semantic values if user action cuts parse. ##
921 ## ------------------------------------------------------------------------- ##
922
923 AT_SETUP([Leaked semantic values if user action cuts parse])
924
925 AT_BISON_OPTION_PUSHDEFS
926 AT_DATA_GRAMMAR([glr-regr12.y],
927 [[
928 %glr-parser
929 %union { int dummy; }
930 %token PARENT_RHS_AFTER
931 %type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
932 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
933 %destructor { merged_value = 0; } merged
934 %destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
935
936 %{
937 # include <stdlib.h>
938 # include <assert.h>
939 static int merge (YYSTYPE, YYSTYPE);
940 ]AT_YYERROR_DECLARE[
941 ]AT_YYLEX_DECLARE[
942 static int parent_rhs_before_value = 0;
943 static int merged_value = 0;
944 static int parent_rhs_after_value = 0;
945 # define USE(val)
946 %}
947
948 %%
949
950 start:
951 alt1 %dprec 1
952 | alt2 %dprec 2
953 ;
954
955 alt1:
956 PARENT_RHS_AFTER {
957 USE ($1);
958 parent_rhs_after_value = 0;
959 }
960 ;
961
962 alt2:
963 parent_rhs_before merged PARENT_RHS_AFTER {
964 USE (($1, $2, $3));
965 parent_rhs_before_value = 0;
966 merged_value = 0;
967 parent_rhs_after_value = 0;
968 }
969 ;
970
971 parent_rhs_before:
972 {
973 USE ($$);
974 parent_rhs_before_value = 1;
975 }
976 ;
977
978 merged:
979 %merge<merge> {
980 USE ($$);
981 merged_value = 1;
982 }
983 | cut %merge<merge> {
984 USE ($$);
985 merged_value = 1;
986 }
987 ;
988
989 cut: { YYACCEPT; } ;
990
991 %%
992
993 static int
994 merge (YYSTYPE s1, YYSTYPE s2)
995 {
996 /* Not invoked. */
997 char dummy = s1.dummy + s2.dummy;
998 return dummy;
999 }
1000
1001 ]AT_YYERROR_DEFINE[
1002 ]AT_YYLEX_DEFINE([{ PARENT_RHS_AFTER, 0 }],
1003 [if (res == PARENT_RHS_AFTER)
1004 parent_rhs_after_value = 1;])[
1005
1006 int
1007 main (void)
1008 {
1009 int exit_status = yyparse ();
1010 if (parent_rhs_before_value)
1011 {
1012 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1013 exit_status = 1;
1014 }
1015 if (merged_value)
1016 {
1017 fprintf (stderr, "`merged' destructor not called.\n");
1018 exit_status = 1;
1019 }
1020 if (parent_rhs_after_value)
1021 {
1022 fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
1023 exit_status = 1;
1024 }
1025 return exit_status;
1026 }
1027 ]])
1028 AT_BISON_OPTION_POPDEFS
1029
1030 AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [],
1031 [[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
1032 glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1033 ]])
1034 AT_COMPILE([glr-regr12])
1035
1036 AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
1037
1038 AT_CLEANUP
1039
1040
1041 ## ------------------------------------------------------------------------- ##
1042 ## Incorrect lookahead during deterministic GLR. See ##
1043 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1044 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
1045 ## ------------------------------------------------------------------------- ##
1046
1047 AT_SETUP([Incorrect lookahead during deterministic GLR])
1048
1049 AT_BISON_OPTION_PUSHDEFS
1050 AT_DATA_GRAMMAR([glr-regr13.y],
1051 [[
1052 /* Tests:
1053 - Defaulted state with initial yychar: yychar == YYEMPTY.
1054 - Nondefaulted state: yychar != YYEMPTY.
1055 - Defaulted state after lookahead: yychar != YYEMPTY.
1056 - Defaulted state after shift: yychar == YYEMPTY.
1057 - User action changing the lookahead. */
1058
1059 %{
1060 #include <stdio.h>
1061 #include <assert.h>
1062 ]AT_YYERROR_DECLARE[
1063 ]AT_YYLEX_DECLARE[
1064 static void print_lookahead (char const *);
1065 #define USE(value)
1066 %}
1067
1068 %union { char value; }
1069 %type <value> 'a' 'b'
1070 %glr-parser
1071 %locations
1072
1073 %%
1074
1075 start:
1076 defstate_init defstate_shift 'b' change_lookahead 'a' {
1077 USE ($3);
1078 print_lookahead ("start <- defstate_init defstate_shift 'b'");
1079 }
1080 ;
1081 defstate_init:
1082 {
1083 print_lookahead ("defstate_init <- empty string");
1084 }
1085 ;
1086 defstate_shift:
1087 nondefstate defstate_look 'a' {
1088 USE ($3);
1089 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
1090 }
1091 ;
1092 defstate_look:
1093 {
1094 print_lookahead ("defstate_look <- empty string");
1095 }
1096 ;
1097 nondefstate:
1098 {
1099 print_lookahead ("nondefstate <- empty string");
1100 }
1101 | 'b' {
1102 USE ($1);
1103 print_lookahead ("nondefstate <- 'b'");
1104 }
1105 ;
1106 change_lookahead:
1107 {
1108 yychar = 'a';
1109 }
1110 ;
1111
1112 %%
1113
1114 ]AT_YYERROR_DEFINE[
1115 ]AT_YYLEX_DEFINE(["ab"],
1116 [yylval.value = res + 'A' - 'a'])[
1117
1118 static void
1119 print_lookahead (char const *reduction)
1120 {
1121 printf ("%s:\n yychar=", reduction);
1122 if (yychar == YYEMPTY)
1123 printf ("YYEMPTY");
1124 else if (yychar == YYEOF)
1125 printf ("YYEOF");
1126 else
1127 {
1128 printf ("'%c', yylval='", yychar);
1129 if (yylval.value > ' ')
1130 printf ("%c", yylval.value);
1131 printf ("', yylloc=(%d,%d),(%d,%d)",
1132 yylloc.first_line, yylloc.first_column,
1133 yylloc.last_line, yylloc.last_column);
1134 }
1135 printf ("\n");
1136 }
1137
1138 int
1139 main (void)
1140 {
1141 yychar = '#'; /* Not a token in the grammar. */
1142 yylval.value = '!';
1143 return yyparse ();
1144 }
1145 ]])
1146 AT_BISON_OPTION_POPDEFS
1147
1148 AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], [])
1149 AT_COMPILE([glr-regr13])
1150
1151 AT_PARSER_CHECK([[./glr-regr13]], 0,
1152 [defstate_init <- empty string:
1153 yychar=YYEMPTY
1154 nondefstate <- empty string:
1155 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1156 defstate_look <- empty string:
1157 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1158 defstate_shift <- nondefstate defstate_look 'a':
1159 yychar=YYEMPTY
1160 start <- defstate_init defstate_shift 'b':
1161 yychar=YYEMPTY
1162 ], [])
1163
1164 AT_CLEANUP
1165
1166
1167 ## ------------------------------------------------------------------------- ##
1168 ## Incorrect lookahead during nondeterministic GLR. ##
1169 ## ------------------------------------------------------------------------- ##
1170
1171 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1172
1173 AT_BISON_OPTION_PUSHDEFS
1174 AT_DATA_GRAMMAR([glr-regr14.y],
1175 [[
1176 /* Tests:
1177 - Conflicting actions (split-off parse, which copies lookahead need,
1178 which is necessarily yytrue) and nonconflicting actions (non-split-off
1179 parse) for nondefaulted state: yychar != YYEMPTY.
1180 - Merged deferred actions (lookahead need and RHS from different stack
1181 than the target state) and nonmerged deferred actions (same stack).
1182 - Defaulted state after lookahead: yychar != YYEMPTY.
1183 - Defaulted state after shift: yychar == YYEMPTY.
1184 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1185 seen the lookahead but current stack has not).
1186 - Exceeding stack capacity (stack explosion), and thus reallocating
1187 lookahead need array.
1188 Note that it does not seem possible to see the initial yychar value during
1189 nondeterministic operation since:
1190 - In order to preserve the initial yychar, only defaulted states may be
1191 entered.
1192 - If only defaulted states are entered, there are no conflicts, so
1193 nondeterministic operation does not start. */
1194
1195 %union { char value; }
1196
1197 %{
1198 #include <stdlib.h>
1199 #include <stdio.h>
1200 #include <assert.h>
1201 ]AT_YYERROR_DECLARE[
1202 ]AT_YYLEX_DECLARE[
1203 static void print_lookahead (char const *);
1204 static char merge (union YYSTYPE, union YYSTYPE);
1205 #define USE(value)
1206 %}
1207
1208 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1209 %glr-parser
1210 %locations
1211
1212 %%
1213
1214 start:
1215 merge 'c' stack_explosion {
1216 USE ($2); USE ($3);
1217 print_lookahead ("start <- merge 'c' stack_explosion");
1218 }
1219 ;
1220
1221 /* When merging the 2 deferred actions, the lookahead needs are different. */
1222 merge:
1223 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1224 USE ($2); USE ($3);
1225 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
1226 }
1227 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1228 USE ($3); USE ($5);
1229 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1230 " defstate_shift");
1231 }
1232 ;
1233
1234 nonconflict1:
1235 {
1236 print_lookahead ("nonconflict1 <- empty string");
1237 }
1238 ;
1239 nonconflict2:
1240 {
1241 print_lookahead ("nonconflict2 <- empty string");
1242 }
1243 | 'a' {
1244 USE ($1);
1245 print_lookahead ("nonconflict2 <- 'a'");
1246 }
1247 ;
1248 conflict:
1249 {
1250 print_lookahead ("conflict <- empty string");
1251 }
1252 ;
1253 defstate_look:
1254 {
1255 print_lookahead ("defstate_look <- empty string");
1256 }
1257 ;
1258
1259 /* yychar != YYEMPTY but lookahead need is yyfalse. */
1260 defstate_shift:
1261 {
1262 print_lookahead ("defstate_shift <- empty string");
1263 }
1264 ;
1265
1266 stack_explosion:
1267 { $$ = '\0'; }
1268 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1269 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1270 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1271 ;
1272 alt1:
1273 'd' no_look {
1274 USE ($1);
1275 if (yychar != 'd' && yychar != YYEOF)
1276 {
1277 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1278 }
1279 }
1280 ;
1281 alt2:
1282 'd' no_look {
1283 USE ($1);
1284 if (yychar != 'd' && yychar != YYEOF)
1285 {
1286 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1287 }
1288 }
1289 ;
1290 alt3:
1291 'd' no_look {
1292 USE ($1);
1293 if (yychar != 'd' && yychar != YYEOF)
1294 {
1295 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1296 }
1297 }
1298 ;
1299 no_look:
1300 {
1301 if (yychar != YYEMPTY)
1302 {
1303 fprintf (stderr,
1304 "Found lookahead where shouldn't during stack explosion.\n");
1305 }
1306 }
1307 ;
1308
1309 %%
1310
1311 ]AT_YYERROR_DEFINE[
1312 static int
1313 yylex (void)
1314 {
1315 static char const input[] = "abcdddd";
1316 static size_t toknum;
1317 assert (toknum < sizeof input);
1318 yylloc.first_line = yylloc.last_line = 1;
1319 yylloc.first_column = yylloc.last_column = toknum + 1;
1320 yylval.value = input[toknum] + 'A' - 'a';
1321 return input[toknum++];
1322 }
1323
1324 static void
1325 print_lookahead (char const *reduction)
1326 {
1327 printf ("%s:\n yychar=", reduction);
1328 if (yychar == YYEMPTY)
1329 printf ("YYEMPTY");
1330 else if (yychar == YYEOF)
1331 printf ("YYEOF");
1332 else
1333 {
1334 printf ("'%c', yylval='", yychar);
1335 if (yylval.value > ' ')
1336 printf ("%c", yylval.value);
1337 printf ("', yylloc=(%d,%d),(%d,%d)",
1338 yylloc.first_line, yylloc.first_column,
1339 yylloc.last_line, yylloc.last_column);
1340 }
1341 printf ("\n");
1342 }
1343
1344 static char
1345 merge (union YYSTYPE s1, union YYSTYPE s2)
1346 {
1347 char dummy = s1.value + s2.value;
1348 return dummy;
1349 }
1350
1351 int
1352 main (void)
1353 {
1354 yychar = '#'; /* Not a token in the grammar. */
1355 yylval.value = '!';
1356 return yyparse ();
1357 }
1358 ]])
1359 AT_BISON_OPTION_POPDEFS
1360
1361 AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
1362 [[glr-regr14.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1363 ]])
1364 AT_COMPILE([glr-regr14])
1365
1366 AT_PARSER_CHECK([[./glr-regr14]], 0,
1367 [conflict <- empty string:
1368 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1369 defstate_look <- empty string:
1370 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1371 nonconflict2 <- empty string:
1372 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1373 defstate_shift <- empty string:
1374 yychar=YYEMPTY
1375 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1376 yychar=YYEMPTY
1377 start <- merge 'c' stack_explosion:
1378 yychar=YYEOF
1379 ], [])
1380
1381 AT_CLEANUP
1382
1383
1384 ## ------------------------------------------------------------------------- ##
1385 ## Leaked semantic values when reporting ambiguity. ##
1386 ## ------------------------------------------------------------------------- ##
1387
1388 AT_SETUP([Leaked semantic values when reporting ambiguity])
1389
1390 AT_BISON_OPTION_PUSHDEFS
1391 AT_DATA_GRAMMAR([glr-regr15.y],
1392 [[
1393 %glr-parser
1394 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1395
1396 %{
1397 # include <stdlib.h>
1398 ]AT_YYERROR_DECLARE[
1399 ]AT_YYLEX_DECLARE[
1400 static int parent_rhs_before_value = 0;
1401 # define USE(val)
1402 %}
1403
1404 %%
1405
1406 start:
1407 alt1 %dprec 1
1408 | alt2 %dprec 2
1409 ;
1410
1411 /* This stack must be merged into the other stacks *last* (added at the
1412 beginning of the semantic options list) so that yyparse will choose to clean
1413 it up rather than the tree for which some semantic actions have been
1414 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1415 those other trees are not cleaned up. */
1416 alt1: ;
1417
1418 alt2:
1419 parent_rhs_before ambiguity {
1420 USE ($1);
1421 parent_rhs_before_value = 0;
1422 }
1423 ;
1424
1425 parent_rhs_before:
1426 {
1427 USE ($$);
1428 parent_rhs_before_value = 1;
1429 }
1430 ;
1431
1432 ambiguity: ambiguity1 | ambiguity2 ;
1433 ambiguity1: ;
1434 ambiguity2: ;
1435
1436 %%
1437 ]AT_YYERROR_DEFINE[
1438 ]AT_YYLEX_DEFINE[
1439
1440 int
1441 main (void)
1442 {
1443 int exit_status = yyparse () != 1;
1444 if (parent_rhs_before_value)
1445 {
1446 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1447 exit_status = 1;
1448 }
1449 return exit_status;
1450 }
1451 ]])
1452 AT_BISON_OPTION_POPDEFS
1453
1454 AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
1455 [[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
1456 ]])
1457 AT_COMPILE([glr-regr15])
1458
1459 AT_PARSER_CHECK([[./glr-regr15]], 0, [],
1460 [syntax is ambiguous
1461 ])
1462
1463 AT_CLEANUP
1464
1465
1466 ## ------------------------------------------------------------------------- ##
1467 ## Leaked lookahead after nondeterministic parse syntax error. ##
1468 ## ------------------------------------------------------------------------- ##
1469
1470 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1471
1472 AT_BISON_OPTION_PUSHDEFS
1473 AT_DATA_GRAMMAR([glr-regr16.y],
1474 [[
1475 %glr-parser
1476 %destructor { lookahead_value = 0; } 'b'
1477
1478 %{
1479 # include <stdlib.h>
1480 # include <assert.h>
1481 ]AT_YYERROR_DECLARE[
1482 ]AT_YYLEX_DECLARE[
1483 static int lookahead_value = 0;
1484 # define USE(val)
1485 %}
1486
1487 %%
1488
1489 start: alt1 'a' | alt2 'a' ;
1490 alt1: ;
1491 alt2: ;
1492
1493 %%
1494
1495 ]AT_YYERROR_DEFINE[
1496 ]AT_YYLEX_DEFINE(["ab"],
1497 [if (res == 'b')
1498 lookahead_value = 1])[
1499
1500 int
1501 main (void)
1502 {
1503 int exit_status = yyparse () != 1;
1504 if (lookahead_value)
1505 {
1506 fprintf (stderr, "Lookahead destructor not called.\n");
1507 exit_status = 1;
1508 }
1509 return exit_status;
1510 }
1511 ]])
1512 AT_BISON_OPTION_POPDEFS
1513
1514 AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
1515 [[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1516 ]])
1517 AT_COMPILE([glr-regr16])
1518
1519 AT_PARSER_CHECK([[./glr-regr16]], 0, [],
1520 [syntax error
1521 ])
1522
1523 AT_CLEANUP
1524
1525
1526 ## ------------------------------------------------------------------------- ##
1527 ## Uninitialized location when reporting ambiguity. ##
1528 ## ------------------------------------------------------------------------- ##
1529
1530 AT_SETUP([Uninitialized location when reporting ambiguity])
1531
1532 AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations %define api.pure])
1533
1534 AT_DATA_GRAMMAR([glr-regr17.y],
1535 [[
1536 %glr-parser
1537 %locations
1538 %define api.pure
1539 %error-verbose
1540
1541 %union { int dummy; }
1542
1543 %{
1544 ]AT_YYERROR_DECLARE[
1545 ]AT_YYLEX_DECLARE[
1546 %}
1547
1548 %initial-action {
1549 @$.first_line = 1;
1550 @$.first_column = 1;
1551 @$.last_line = 1;
1552 @$.last_column = 1;
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: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
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: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
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