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