]> git.saurik.com Git - bison.git/blob - tests/glr-regression.at
tests: factor.
[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
36 #define YYSTYPE int
37 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1);
38 ]AT_YYERROR_DECLARE[
39 ]AT_YYLEX_DECLARE[
40 %}
41
42
43 %glr-parser
44
45
46 /* -------- productions ------ */
47 %%
48
49 StartSymbol: E { $$=0; } %merge <exprMerge>
50 ;
51
52 E: E 'P' E { $$=1; printf("E -> E 'P' E\n"); } %merge <exprMerge>
53 | 'B' { $$=2; printf("E -> 'B'\n"); } %merge <exprMerge>
54 ;
55
56
57
58 /* ---------- C code ----------- */
59 %%
60
61 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1)
62 {
63 (void) x0;
64 (void) x1;
65 printf ("<OR>\n");
66 return 0;
67 }
68
69 int
70 main (void)
71 {
72 return yyparse ();
73 }
74
75 ]AT_YYERROR_DEFINE[
76
77 int
78 yylex (void)
79 {
80 for (;;)
81 {
82 int ch;
83 if (feof (stdin))
84 abort ();
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 ]AT_YYERROR_DECLARE[
132 ]AT_YYLEX_DECLARE[
133 %}
134
135 %glr-parser
136
137 %%
138
139 command:
140 's' var 't'
141 { printf ("Variable: '%s'\n", $2); }
142 'v' 'x' 'q'
143 { free ($2); }
144 | 's' var_list 't' 'e'
145 { printf ("Varlist: '%s'\n", $2); free ($2); }
146 | 's' var 't' var_printer 'x'
147 { free ($2); }
148 ;
149
150 var:
151 'V'
152 { $$ = $1; }
153 ;
154
155 var_list:
156 var
157 { $$ = $1; }
158 | var ',' var_list
159 {
160 char *s = (char *) realloc ($1, strlen ($1) + 1 + strlen ($3) + 1);
161 strcat (s, ",");
162 strcat (s, $3);
163 free ($3);
164 $$ = s;
165 }
166 ;
167
168 var_printer: 'v'
169 { printf ("Variable: '%s'\n", $-1); }
170
171 %%
172 ]AT_YYERROR_DEFINE[
173 FILE *input;
174
175 int
176 yylex (void)
177 {
178 char buf[50];
179 char *s;
180 if (feof (stdin))
181 abort ();
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 if (sizeof buf - 1 <= strlen (buf))
194 abort ();
195 s = (char *) malloc (strlen (buf) + 1);
196 strcpy (s, buf);
197 yylval = s;
198 return 'V';
199 }
200
201 int
202 main (int argc, char **argv)
203 {
204 input = stdin;
205 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
206 return yyparse ();
207 }
208 ]])
209 AT_BISON_OPTION_POPDEFS
210
211 AT_BISON_CHECK([[-o glr-regr2a.c glr-regr2a.y]], 0, [],
212 [glr-regr2a.y: conflicts: 2 shift/reduce
213 ])
214 AT_COMPILE([glr-regr2a])
215
216 AT_PARSER_CHECK([[echo s VARIABLE_1 t v x q | ./glr-regr2a]], 0,
217 [[Variable: 'VARIABLE_1'
218 ]], [])
219 AT_PARSER_CHECK([[echo s VARIABLE_1 , ANOTHER_VARIABLE_2 t e | ./glr-regr2a]],
220 0,
221 [[Varlist: 'VARIABLE_1,ANOTHER_VARIABLE_2'
222 ]])
223 AT_PARSER_CHECK([[echo s VARIABLE_3 t v x | ./glr-regr2a]], 0,
224 [[Variable: 'VARIABLE_3'
225 ]], [])
226
227
228 AT_CLEANUP
229
230 ## ------------------------------------------------------------ ##
231 ## Improper merging of GLR delayed action sets ##
232 ## ------------------------------------------------------------ ##
233
234 AT_SETUP([Improper merging of GLR delayed action sets])
235
236 AT_BISON_OPTION_PUSHDEFS
237 AT_DATA_GRAMMAR([glr-regr3.y],
238 [[/* Regression Test: Improper merging of GLR delayed action sets. */
239 /* Reported by M. Rosien */
240
241 %{
242 #include <stdio.h>
243 #include <stdlib.h>
244 #include <stdarg.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 if (feof (stdin))
306 abort ();
307 if (fscanf (input, "%2s", inp) == EOF)
308 return 0;
309 switch (inp[0])
310 {
311 case 'p': return P[inp[1] - '1'];
312 case 't': return T[inp[1] - '1'];
313 case 'o': return O[inp[1] - '1'];
314 }
315 return BAD_CHAR;
316 }
317
318 int
319 main(int argc, char* argv[])
320 {
321 input = stdin;
322 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
323 return yyparse ();
324 }
325 ]])
326 AT_BISON_OPTION_POPDEFS
327
328 AT_BISON_CHECK([[-o glr-regr3.c glr-regr3.y]], 0, [],
329 [glr-regr3.y: conflicts: 1 shift/reduce, 1 reduce/reduce
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: conflicts: 1 reduce/reduce
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: conflicts: 1 reduce/reduce
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: conflicts: 1 reduce/reduce
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: conflicts: 2 reduce/reduce
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: conflicts: 1 reduce/reduce
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: conflicts: 1 reduce/reduce
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: conflicts: 1 reduce/reduce
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: conflicts: 1 reduce/reduce
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 static int merge (YYSTYPE, YYSTYPE);
939 ]AT_YYERROR_DECLARE[
940 ]AT_YYLEX_DECLARE[
941 static int parent_rhs_before_value = 0;
942 static int merged_value = 0;
943 static int parent_rhs_after_value = 0;
944 # define USE(val)
945 %}
946
947 %%
948
949 start:
950 alt1 %dprec 1
951 | alt2 %dprec 2
952 ;
953
954 alt1:
955 PARENT_RHS_AFTER {
956 USE ($1);
957 parent_rhs_after_value = 0;
958 }
959 ;
960
961 alt2:
962 parent_rhs_before merged PARENT_RHS_AFTER {
963 USE (($1, $2, $3));
964 parent_rhs_before_value = 0;
965 merged_value = 0;
966 parent_rhs_after_value = 0;
967 }
968 ;
969
970 parent_rhs_before:
971 {
972 USE ($$);
973 parent_rhs_before_value = 1;
974 }
975 ;
976
977 merged:
978 %merge<merge> {
979 USE ($$);
980 merged_value = 1;
981 }
982 | cut %merge<merge> {
983 USE ($$);
984 merged_value = 1;
985 }
986 ;
987
988 cut: { YYACCEPT; } ;
989
990 %%
991
992 static int
993 merge (YYSTYPE s1, YYSTYPE s2)
994 {
995 /* Not invoked. */
996 char dummy = s1.dummy + s2.dummy;
997 return dummy;
998 }
999
1000 ]AT_YYERROR_DEFINE[
1001 static int
1002 yylex (void)
1003 {
1004 static int const input[] = { PARENT_RHS_AFTER, 0 };
1005 static size_t toknum;
1006 if (! (toknum < sizeof input / sizeof *input))
1007 abort ();
1008 if (input[toknum] == PARENT_RHS_AFTER)
1009 parent_rhs_after_value = 1;
1010 return input[toknum++];
1011 }
1012
1013 int
1014 main (void)
1015 {
1016 int exit_status = yyparse ();
1017 if (parent_rhs_before_value)
1018 {
1019 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1020 exit_status = 1;
1021 }
1022 if (merged_value)
1023 {
1024 fprintf (stderr, "`merged' destructor not called.\n");
1025 exit_status = 1;
1026 }
1027 if (parent_rhs_after_value)
1028 {
1029 fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
1030 exit_status = 1;
1031 }
1032 return exit_status;
1033 }
1034 ]])
1035 AT_BISON_OPTION_POPDEFS
1036
1037 AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [],
1038 [glr-regr12.y: conflicts: 1 shift/reduce, 1 reduce/reduce
1039 ])
1040 AT_COMPILE([glr-regr12])
1041
1042 AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
1043
1044 AT_CLEANUP
1045
1046
1047 ## ------------------------------------------------------------------------- ##
1048 ## Incorrect lookahead during deterministic GLR. See ##
1049 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1050 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
1051 ## ------------------------------------------------------------------------- ##
1052
1053 AT_SETUP([Incorrect lookahead during deterministic GLR])
1054
1055 AT_BISON_OPTION_PUSHDEFS
1056 AT_DATA_GRAMMAR([glr-regr13.y],
1057 [[
1058 /* Tests:
1059 - Defaulted state with initial yychar: yychar == YYEMPTY.
1060 - Nondefaulted state: yychar != YYEMPTY.
1061 - Defaulted state after lookahead: yychar != YYEMPTY.
1062 - Defaulted state after shift: yychar == YYEMPTY.
1063 - User action changing the lookahead. */
1064
1065 %{
1066 #include <stdio.h>
1067 ]AT_YYERROR_DECLARE[
1068 ]AT_YYLEX_DECLARE[
1069 static void print_lookahead (char const *);
1070 #define USE(value)
1071 %}
1072
1073 %union { char value; }
1074 %type <value> 'a' 'b'
1075 %glr-parser
1076 %locations
1077
1078 %%
1079
1080 start:
1081 defstate_init defstate_shift 'b' change_lookahead 'a' {
1082 USE ($3);
1083 print_lookahead ("start <- defstate_init defstate_shift 'b'");
1084 }
1085 ;
1086 defstate_init:
1087 {
1088 print_lookahead ("defstate_init <- empty string");
1089 }
1090 ;
1091 defstate_shift:
1092 nondefstate defstate_look 'a' {
1093 USE ($3);
1094 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
1095 }
1096 ;
1097 defstate_look:
1098 {
1099 print_lookahead ("defstate_look <- empty string");
1100 }
1101 ;
1102 nondefstate:
1103 {
1104 print_lookahead ("nondefstate <- empty string");
1105 }
1106 | 'b' {
1107 USE ($1);
1108 print_lookahead ("nondefstate <- 'b'");
1109 }
1110 ;
1111 change_lookahead:
1112 {
1113 yychar = 'a';
1114 }
1115 ;
1116
1117 %%
1118
1119 ]AT_YYERROR_DEFINE[
1120 static int
1121 yylex (void)
1122 {
1123 static char const input[] = "ab";
1124 static size_t toknum;
1125 if (! (toknum < sizeof input))
1126 abort ();
1127 yylloc.first_line = yylloc.last_line = 1;
1128 yylloc.first_column = yylloc.last_column = toknum + 1;
1129 yylval.value = input[toknum] + 'A' - 'a';
1130 return input[toknum++];
1131 }
1132
1133 static void
1134 print_lookahead (char const *reduction)
1135 {
1136 printf ("%s:\n yychar=", reduction);
1137 if (yychar == YYEMPTY)
1138 printf ("YYEMPTY");
1139 else if (yychar == YYEOF)
1140 printf ("YYEOF");
1141 else
1142 {
1143 printf ("'%c', yylval='", yychar);
1144 if (yylval.value > ' ')
1145 printf ("%c", yylval.value);
1146 printf ("', yylloc=(%d,%d),(%d,%d)",
1147 yylloc.first_line, yylloc.first_column,
1148 yylloc.last_line, yylloc.last_column);
1149 }
1150 printf ("\n");
1151 }
1152
1153 int
1154 main (void)
1155 {
1156 yychar = '#'; /* Not a token in the grammar. */
1157 yylval.value = '!';
1158 return yyparse ();
1159 }
1160 ]])
1161 AT_BISON_OPTION_POPDEFS
1162
1163 AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], [])
1164 AT_COMPILE([glr-regr13])
1165
1166 AT_PARSER_CHECK([[./glr-regr13]], 0,
1167 [defstate_init <- empty string:
1168 yychar=YYEMPTY
1169 nondefstate <- empty string:
1170 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1171 defstate_look <- empty string:
1172 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1173 defstate_shift <- nondefstate defstate_look 'a':
1174 yychar=YYEMPTY
1175 start <- defstate_init defstate_shift 'b':
1176 yychar=YYEMPTY
1177 ], [])
1178
1179 AT_CLEANUP
1180
1181
1182 ## ------------------------------------------------------------------------- ##
1183 ## Incorrect lookahead during nondeterministic GLR. ##
1184 ## ------------------------------------------------------------------------- ##
1185
1186 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1187
1188 AT_BISON_OPTION_PUSHDEFS
1189 AT_DATA_GRAMMAR([glr-regr14.y],
1190 [[
1191 /* Tests:
1192 - Conflicting actions (split-off parse, which copies lookahead need,
1193 which is necessarily yytrue) and nonconflicting actions (non-split-off
1194 parse) for nondefaulted state: yychar != YYEMPTY.
1195 - Merged deferred actions (lookahead need and RHS from different stack
1196 than the target state) and nonmerged deferred actions (same stack).
1197 - Defaulted state after lookahead: yychar != YYEMPTY.
1198 - Defaulted state after shift: yychar == YYEMPTY.
1199 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1200 seen the lookahead but current stack has not).
1201 - Exceeding stack capacity (stack explosion), and thus reallocating
1202 lookahead need array.
1203 Note that it does not seem possible to see the initial yychar value during
1204 nondeterministic operation since:
1205 - In order to preserve the initial yychar, only defaulted states may be
1206 entered.
1207 - If only defaulted states are entered, there are no conflicts, so
1208 nondeterministic operation does not start. */
1209
1210 %union { char value; }
1211
1212 %{
1213 #include <stdlib.h>
1214 #include <stdio.h>
1215 ]AT_YYERROR_DECLARE[
1216 ]AT_YYLEX_DECLARE[
1217 static void print_lookahead (char const *);
1218 static char merge (union YYSTYPE, union YYSTYPE);
1219 #define USE(value)
1220 %}
1221
1222 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1223 %glr-parser
1224 %locations
1225
1226 %%
1227
1228 start:
1229 merge 'c' stack_explosion {
1230 USE ($2); USE ($3);
1231 print_lookahead ("start <- merge 'c' stack_explosion");
1232 }
1233 ;
1234
1235 /* When merging the 2 deferred actions, the lookahead needs are different. */
1236 merge:
1237 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1238 USE ($2); USE ($3);
1239 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
1240 }
1241 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1242 USE ($3); USE ($5);
1243 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1244 " defstate_shift");
1245 }
1246 ;
1247
1248 nonconflict1:
1249 {
1250 print_lookahead ("nonconflict1 <- empty string");
1251 }
1252 ;
1253 nonconflict2:
1254 {
1255 print_lookahead ("nonconflict2 <- empty string");
1256 }
1257 | 'a' {
1258 USE ($1);
1259 print_lookahead ("nonconflict2 <- 'a'");
1260 }
1261 ;
1262 conflict:
1263 {
1264 print_lookahead ("conflict <- empty string");
1265 }
1266 ;
1267 defstate_look:
1268 {
1269 print_lookahead ("defstate_look <- empty string");
1270 }
1271 ;
1272
1273 /* yychar != YYEMPTY but lookahead need is yyfalse. */
1274 defstate_shift:
1275 {
1276 print_lookahead ("defstate_shift <- empty string");
1277 }
1278 ;
1279
1280 stack_explosion:
1281 { $$ = '\0'; }
1282 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1283 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1284 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1285 ;
1286 alt1:
1287 'd' no_look {
1288 USE ($1);
1289 if (yychar != 'd' && yychar != YYEOF)
1290 {
1291 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1292 }
1293 }
1294 ;
1295 alt2:
1296 'd' no_look {
1297 USE ($1);
1298 if (yychar != 'd' && yychar != YYEOF)
1299 {
1300 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1301 }
1302 }
1303 ;
1304 alt3:
1305 'd' no_look {
1306 USE ($1);
1307 if (yychar != 'd' && yychar != YYEOF)
1308 {
1309 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1310 }
1311 }
1312 ;
1313 no_look:
1314 {
1315 if (yychar != YYEMPTY)
1316 {
1317 fprintf (stderr,
1318 "Found lookahead where shouldn't during stack explosion.\n");
1319 }
1320 }
1321 ;
1322
1323 %%
1324
1325 ]AT_YYERROR_DEFINE[
1326 static int
1327 yylex (void)
1328 {
1329 static char const input[] = "abcdddd";
1330 static size_t toknum;
1331 if (! (toknum < sizeof input))
1332 abort ();
1333 yylloc.first_line = yylloc.last_line = 1;
1334 yylloc.first_column = yylloc.last_column = toknum + 1;
1335 yylval.value = input[toknum] + 'A' - 'a';
1336 return input[toknum++];
1337 }
1338
1339 static void
1340 print_lookahead (char const *reduction)
1341 {
1342 printf ("%s:\n yychar=", reduction);
1343 if (yychar == YYEMPTY)
1344 printf ("YYEMPTY");
1345 else if (yychar == YYEOF)
1346 printf ("YYEOF");
1347 else
1348 {
1349 printf ("'%c', yylval='", yychar);
1350 if (yylval.value > ' ')
1351 printf ("%c", yylval.value);
1352 printf ("', yylloc=(%d,%d),(%d,%d)",
1353 yylloc.first_line, yylloc.first_column,
1354 yylloc.last_line, yylloc.last_column);
1355 }
1356 printf ("\n");
1357 }
1358
1359 static char
1360 merge (union YYSTYPE s1, union YYSTYPE s2)
1361 {
1362 char dummy = s1.value + s2.value;
1363 return dummy;
1364 }
1365
1366 int
1367 main (void)
1368 {
1369 yychar = '#'; /* Not a token in the grammar. */
1370 yylval.value = '!';
1371 return yyparse ();
1372 }
1373 ]])
1374 AT_BISON_OPTION_POPDEFS
1375
1376 AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
1377 [glr-regr14.y: conflicts: 3 reduce/reduce
1378 ])
1379 AT_COMPILE([glr-regr14])
1380
1381 AT_PARSER_CHECK([[./glr-regr14]], 0,
1382 [conflict <- empty string:
1383 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1384 defstate_look <- empty string:
1385 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1386 nonconflict2 <- empty string:
1387 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1388 defstate_shift <- empty string:
1389 yychar=YYEMPTY
1390 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1391 yychar=YYEMPTY
1392 start <- merge 'c' stack_explosion:
1393 yychar=YYEOF
1394 ], [])
1395
1396 AT_CLEANUP
1397
1398
1399 ## ------------------------------------------------------------------------- ##
1400 ## Leaked semantic values when reporting ambiguity. ##
1401 ## ------------------------------------------------------------------------- ##
1402
1403 AT_SETUP([Leaked semantic values when reporting ambiguity])
1404
1405 AT_BISON_OPTION_PUSHDEFS
1406 AT_DATA_GRAMMAR([glr-regr15.y],
1407 [[
1408 %glr-parser
1409 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1410
1411 %{
1412 # include <stdlib.h>
1413 ]AT_YYERROR_DECLARE[
1414 ]AT_YYLEX_DECLARE[
1415 static int parent_rhs_before_value = 0;
1416 # define USE(val)
1417 %}
1418
1419 %%
1420
1421 start:
1422 alt1 %dprec 1
1423 | alt2 %dprec 2
1424 ;
1425
1426 /* This stack must be merged into the other stacks *last* (added at the
1427 beginning of the semantic options list) so that yyparse will choose to clean
1428 it up rather than the tree for which some semantic actions have been
1429 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1430 those other trees are not cleaned up. */
1431 alt1: ;
1432
1433 alt2:
1434 parent_rhs_before ambiguity {
1435 USE ($1);
1436 parent_rhs_before_value = 0;
1437 }
1438 ;
1439
1440 parent_rhs_before:
1441 {
1442 USE ($$);
1443 parent_rhs_before_value = 1;
1444 }
1445 ;
1446
1447 ambiguity: ambiguity1 | ambiguity2 ;
1448 ambiguity1: ;
1449 ambiguity2: ;
1450
1451 %%
1452 ]AT_YYERROR_DEFINE[
1453 ]AT_YYLEX_DEFINE()[
1454
1455 int
1456 main (void)
1457 {
1458 int exit_status = yyparse () != 1;
1459 if (parent_rhs_before_value)
1460 {
1461 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1462 exit_status = 1;
1463 }
1464 return exit_status;
1465 }
1466 ]])
1467 AT_BISON_OPTION_POPDEFS
1468
1469 AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
1470 [glr-regr15.y: conflicts: 2 reduce/reduce
1471 ])
1472 AT_COMPILE([glr-regr15])
1473
1474 AT_PARSER_CHECK([[./glr-regr15]], 0, [],
1475 [syntax is ambiguous
1476 ])
1477
1478 AT_CLEANUP
1479
1480
1481 ## ------------------------------------------------------------------------- ##
1482 ## Leaked lookahead after nondeterministic parse syntax error. ##
1483 ## ------------------------------------------------------------------------- ##
1484
1485 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1486
1487 AT_BISON_OPTION_PUSHDEFS
1488 AT_DATA_GRAMMAR([glr-regr16.y],
1489 [[
1490 %glr-parser
1491 %destructor { lookahead_value = 0; } 'b'
1492
1493 %{
1494 # include <stdlib.h>
1495 ]AT_YYERROR_DECLARE[
1496 ]AT_YYLEX_DECLARE[
1497 static int lookahead_value = 0;
1498 # define USE(val)
1499 %}
1500
1501 %%
1502
1503 start: alt1 'a' | alt2 'a' ;
1504 alt1: ;
1505 alt2: ;
1506
1507 %%
1508
1509 ]AT_YYERROR_DEFINE[
1510 static int
1511 yylex (void)
1512 {
1513 static char const input[] = "ab";
1514 static size_t toknum;
1515 if (! (toknum < sizeof input))
1516 abort ();
1517 if (input[toknum] == 'b')
1518 lookahead_value = 1;
1519 return input[toknum++];
1520 }
1521
1522 int
1523 main (void)
1524 {
1525 int exit_status = yyparse () != 1;
1526 if (lookahead_value)
1527 {
1528 fprintf (stderr, "Lookahead destructor not called.\n");
1529 exit_status = 1;
1530 }
1531 return exit_status;
1532 }
1533 ]])
1534 AT_BISON_OPTION_POPDEFS
1535
1536 AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
1537 [glr-regr16.y: conflicts: 1 reduce/reduce
1538 ])
1539 AT_COMPILE([glr-regr16])
1540
1541 AT_PARSER_CHECK([[./glr-regr16]], 0, [],
1542 [syntax error
1543 ])
1544
1545 AT_CLEANUP
1546
1547
1548 ## ------------------------------------------------------------------------- ##
1549 ## Uninitialized location when reporting ambiguity. ##
1550 ## ------------------------------------------------------------------------- ##
1551
1552 AT_SETUP([Uninitialized location when reporting ambiguity])
1553
1554 AT_BISON_OPTION_PUSHDEFS
1555 AT_DATA_GRAMMAR([glr-regr17.y],
1556 [[
1557 %glr-parser
1558 %locations
1559 %define api.pure
1560 %error-verbose
1561
1562 %union { int dummy; }
1563
1564 %{
1565 static void yyerror (YYLTYPE *, char const *);
1566 static int yylex (YYSTYPE *, YYLTYPE *);
1567 %}
1568
1569 %initial-action {
1570 @$.first_line = 1;
1571 @$.first_column = 1;
1572 @$.last_line = 1;
1573 @$.last_column = 1;
1574 }
1575
1576 %%
1577
1578 /* Tests the case of an empty RHS that has inherited the location of the
1579 previous nonterminal, which is unresolved. That location is reported as the
1580 last position of the ambiguity. */
1581 start: ambig1 empty1 | ambig2 empty2 ;
1582
1583 /* Tests multiple levels of yyresolveLocations recursion. */
1584 ambig1: sub_ambig1 | sub_ambig2 ;
1585 ambig2: sub_ambig1 | sub_ambig2 ;
1586
1587 /* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1588 has inherited the initial location. The empty RHS's location is reported as
1589 the first position in the ambiguity. */
1590 sub_ambig1: empty1 'a' 'b' ;
1591 sub_ambig2: empty2 'a' 'b' ;
1592 empty1: ;
1593 empty2: ;
1594
1595 %%
1596
1597 static void
1598 yyerror (YYLTYPE *locp, char const *msg)
1599 {
1600 fprintf (stderr, "%d.%d-%d.%d: %s.\n", locp->first_line,
1601 locp->first_column, locp->last_line, locp->last_column, msg);
1602 }
1603
1604 static int
1605 yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1606 {
1607 static char const input[] = "ab";
1608 static size_t toknum;
1609 if (! (toknum < sizeof input))
1610 abort ();
1611 lvalp->dummy = 0;
1612 llocp->first_line = llocp->last_line = 2;
1613 llocp->first_column = toknum + 1;
1614 llocp->last_column = llocp->first_column + 1;
1615 return input[toknum++];
1616 }
1617
1618 int
1619 main (void)
1620 {
1621 return yyparse () != 1;
1622 }
1623 ]])
1624 AT_BISON_OPTION_POPDEFS
1625
1626 AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [],
1627 [glr-regr17.y: conflicts: 3 reduce/reduce
1628 ])
1629 AT_COMPILE([glr-regr17])
1630
1631 AT_PARSER_CHECK([[./glr-regr17]], 0, [],
1632 [1.1-2.3: syntax is ambiguous.
1633 ])
1634
1635 AT_CLEANUP
1636
1637
1638 ## -------------------------------------------------------------##
1639 ## Missed %merge type warnings when LHS type is declared later. ##
1640 ## -------------------------------------------------------------##
1641
1642 AT_SETUP([Missed %merge type warnings when LHS type is declared later])
1643
1644 AT_BISON_OPTION_PUSHDEFS
1645 AT_DATA_GRAMMAR([glr-regr18.y],
1646 [[%glr-parser
1647
1648 %{
1649 #include <stdlib.h>
1650 ]AT_YYERROR_DECLARE[
1651 ]AT_YYLEX_DECLARE[
1652 %}
1653
1654 %union {
1655 int type1;
1656 int type2;
1657 int type3;
1658 }
1659
1660 %%
1661
1662 sym1: sym2 %merge<merge> { $$ = $1; } ;
1663 sym2: sym3 %merge<merge> { $$ = $1; } ;
1664 sym3: %merge<merge> { $$ = 0; } ;
1665
1666 %type <type1> sym1;
1667 %type <type2> sym2;
1668 %type <type3> sym3;
1669
1670 %%
1671 ]AT_YYERROR_DEFINE[
1672 ]AT_YYLEX_DEFINE()[
1673 int
1674 main (void)
1675 {
1676 return yyparse ();
1677 }
1678 ]])
1679 AT_BISON_OPTION_POPDEFS
1680
1681 AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
1682 [glr-regr18.y:26.18-24: result type clash on merge function 'merge': <type2> != <type1>
1683 glr-regr18.y:25.18-24: previous declaration
1684 glr-regr18.y:27.13-19: result type clash on merge function 'merge': <type3> != <type2>
1685 glr-regr18.y:26.18-24: previous declaration
1686 ])
1687
1688 AT_CLEANUP
1689
1690
1691 ## ------------------- ##
1692 ## Ambiguity reports. ##
1693 ## ------------------- ##
1694
1695 AT_SETUP([Ambiguity reports])
1696
1697 AT_BISON_OPTION_PUSHDEFS
1698 AT_DATA_GRAMMAR([input.y],
1699 [[
1700 %{
1701 #include <stdio.h>
1702 #include <stdlib.h>
1703 ]AT_YYERROR_DECLARE[
1704 ]AT_YYLEX_DECLARE[
1705 %}
1706
1707 %debug
1708 %glr-parser
1709
1710 %%
1711 start:
1712 'a' b 'c' d
1713 | 'a' b 'c' d
1714 ;
1715 b: 'b';
1716 d: /* nada. */;
1717 %%
1718 ]AT_YYLEX_DEFINE([abc])[
1719 ]AT_YYERROR_DEFINE[
1720 int
1721 main (void)
1722 {
1723 yydebug = 1;
1724 return !!yyparse ();
1725 }
1726 ]])
1727 AT_BISON_OPTION_POPDEFS
1728
1729 AT_BISON_CHECK([[-o input.c input.y]], 0, [],
1730 [input.y: conflicts: 1 reduce/reduce
1731 ])
1732 AT_COMPILE([input])
1733
1734 AT_PARSER_CHECK([[./input]], 1, [],
1735 [Starting parse
1736 Entering state 0
1737 Reading a token: Next token is token 'a' ()
1738 Shifting token 'a' ()
1739 Entering state 1
1740 Reading a token: Next token is token 'b' ()
1741 Shifting token 'b' ()
1742 Entering state 3
1743 Reducing stack 0 by rule 3 (line 25):
1744 $1 = token 'b' ()
1745 -> $$ = nterm b ()
1746 Entering state 4
1747 Reading a token: Next token is token 'c' ()
1748 Shifting token 'c' ()
1749 Entering state 6
1750 Reducing stack 0 by rule 4 (line 26):
1751 -> $$ = nterm d ()
1752 Entering state 7
1753 Reading a token: Now at end of input.
1754 Stack 0 Entering state 7
1755 Now at end of input.
1756 Splitting off stack 1 from 0.
1757 Reduced stack 1 by rule #2; action deferred. Now in state 2.
1758 Stack 1 Entering state 2
1759 Now at end of input.
1760 Reduced stack 0 by rule #1; action deferred. Now in state 2.
1761 Merging stack 0 into stack 1.
1762 Stack 1 Entering state 2
1763 Now at end of input.
1764 Removing dead stacks.
1765 Rename stack 1 -> 0.
1766 On stack 0, shifting token $end ()
1767 Stack 0 now in state #5
1768 Ambiguity detected.
1769 Option 1,
1770 start -> <Rule 1, tokens 1 .. 3>
1771 'a' <tokens 1 .. 1>
1772 b <tokens 2 .. 2>
1773 'c' <tokens 3 .. 3>
1774 d <empty>
1775
1776 Option 2,
1777 start -> <Rule 2, tokens 1 .. 3>
1778 'a' <tokens 1 .. 1>
1779 b <tokens 2 .. 2>
1780 'c' <tokens 3 .. 3>
1781 d <empty>
1782
1783 syntax is ambiguous
1784 Cleanup: popping token $end ()
1785 Cleanup: popping unresolved nterm start ()
1786 Cleanup: popping nterm d ()
1787 Cleanup: popping token 'c' ()
1788 Cleanup: popping nterm b ()
1789 Cleanup: popping token 'a' ()
1790 ])
1791
1792 AT_CLEANUP