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