]> git.saurik.com Git - bison.git/blame - tests/actions.at
-Wempty-rule: diagnose empty rules without %empty
[bison.git] / tests / actions.at
CommitLineData
9534d2be 1e# Executing Actions. -*- Autotest -*-
7d424de1 2
7d6bad19 3# Copyright (C) 2001-2013 Free Software Foundation, Inc.
82c035a8 4
f16b0819 5# This program is free software: you can redistribute it and/or modify
82c035a8 6# it under the terms of the GNU General Public License as published by
f16b0819
PE
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
82c035a8
AD
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
f16b0819 14#
82c035a8 15# You should have received a copy of the GNU General Public License
f16b0819 16# along with this program. If not, see <http://www.gnu.org/licenses/>.
82c035a8
AD
17
18AT_BANNER([[User Actions.]])
19
20## ------------------ ##
21## Mid-rule actions. ##
22## ------------------ ##
23
24AT_SETUP([Mid-rule actions])
25
26# Bison once forgot the mid-rule actions. It was because the action
27# was attached to the host rule (the one with the mid-rule action),
28# instead of being attached to the empty rule dedicated to this
29# action.
30
55f48c48 31AT_BISON_OPTION_PUSHDEFS
9501dc6e 32AT_DATA_GRAMMAR([[input.y]],
cf499cff 33[[%define parse.error verbose
8f3596a6 34%debug
f0f95a50 35%code {
55f48c48
AD
36]AT_YYERROR_DECLARE[
37]AT_YYLEX_DECLARE[
f0f95a50 38}
82c035a8 39%%
931394cb
AD
40exp: { putchar ('0'); }
41 '1' { putchar ('1'); }
42 '2' { putchar ('2'); }
43 '3' { putchar ('3'); }
44 '4' { putchar ('4'); }
45 '5' { putchar ('5'); }
46 '6' { putchar ('6'); }
47 '7' { putchar ('7'); }
48 '8' { putchar ('8'); }
49 '9' { putchar ('9'); }
50 { putchar ('\n'); }
82c035a8
AD
51 ;
52%%
55f48c48 53]AT_YYERROR_DEFINE[
95361618 54]AT_YYLEX_DEFINE(["123456789"])[
3ef9fa8f 55]AT_MAIN_DEFINE[
82c035a8 56]])
55f48c48 57AT_BISON_OPTION_POPDEFS
82c035a8 58
da730230 59AT_BISON_CHECK([-d -v -o input.c input.y])
1154cced
AD
60AT_COMPILE([input])
61AT_PARSER_CHECK([./input], 0,
931394cb 62[[0123456789
82c035a8
AD
63]])
64
65AT_CLEANUP
75d1fe16 66
f68a49ed
AD
67## ----------------------- ##
68## Implicitly empty rule. ##
69## ----------------------- ##
70
71AT_SETUP([Implicitly empty rule])
72
73AT_DATA_GRAMMAR([[1.y]],
74[[%%
75exp: a b;
76a: /* empty. */ {};
77// A mid-rule action does not count as an empty rule.
78b: {} {};
79]])
80
81AT_BISON_CHECK([-fcaret -Wempty-rule 1.y], [0], [],
82[[1.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
83 a: /* empty. */ {};
84 ^^
85]])
86
87AT_CLEANUP
88
ae2b48f5
AD
89## ------------------------ ##
90## Invalid uses of %empty. ##
91## ------------------------ ##
92
93AT_SETUP([Invalid uses of %empty])
94
95AT_DATA_GRAMMAR([[one.y]],
96[[%%
97exp:
98 %empty %empty {}
99;
100]])
101
102AT_BISON_CHECK([-fcaret one.y], [1], [],
103[[one.y:11.10-15: error: only one %empty allowed per rule
104 %empty %empty {}
105 ^^^^^^
106]])
107
108AT_DATA_GRAMMAR([[two.y]],
109[[%%
110exp:
111 'a' %empty {}
112| %empty 'a' {}
113| %empty {} {}
114;
115]])
116
117AT_BISON_CHECK([-fcaret two.y], [1], [],
118[[two.y:11.7-12: error: %empty on non-empty rule
119 'a' %empty {}
120 ^^^^^^
121two.y:12.3-8: error: %empty on non-empty rule
122 | %empty 'a' {}
123 ^^^^^^
124two.y:13.3-8: error: %empty on non-empty rule
125 | %empty {} {}
126 ^^^^^^
127]])
128
129AT_CLEANUP
130
131## ---------------------- ##
132## Valid uses of %empty. ##
133## ---------------------- ##
134
135AT_SETUP([Valid uses of %empty])
136
137AT_BISON_OPTION_PUSHDEFS
138AT_DATA_GRAMMAR([[input.y]],
139[[
140%debug
141%code
142{
143]AT_YYERROR_DECLARE[
144]AT_YYLEX_DECLARE[
145}
146%%
147exp: %empty {}
148%%
149]AT_YYERROR_DEFINE[
150]AT_YYLEX_DEFINE[
151]AT_MAIN_DEFINE[
152]])
153
154AT_FULL_COMPILE([input])
155AT_PARSER_CHECK([./input])
156AT_BISON_OPTION_POPDEFS
157AT_CLEANUP
75d1fe16 158
a1d1ab50
AD
159## ------------------ ##
160## Initial location. ##
161## ------------------ ##
162
fb4c8a7c
TR
163# AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES], [LOCATION = 1.1])
164# -----------------------------------------------------------------------
63951be2 165# Check that the initial location is correct.
a1d1ab50
AD
166m4_pushdef([AT_TEST],
167[AT_SETUP([Initial location: $1 $2])
168
6428a8a4 169AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1" $2])
a1d1ab50 170AT_DATA_GRAMMAR([[input.y]],
66fb016e 171[[%locations
a1d1ab50
AD
172%debug
173%skeleton "$1"
fb4c8a7c
TR
174]$2[
175]$3[
a1d1ab50
AD
176%code
177{
178# include <stdio.h>
1127a75a 179# include <stdlib.h> /* getenv */
a1d1ab50
AD
180]AT_YYERROR_DECLARE[
181]AT_YYLEX_DECLARE[
182}
183%%
184exp: { ]AT_SKEL_CC_IF([[std::cerr << @$ << std::endl]],
f0f95a50 185 [[LOCATION_PRINT(stderr, @$); fputc ('\n', stderr)]])[; }
a1d1ab50
AD
186%%
187]AT_YYERROR_DEFINE[
188
189]AT_YYLEX_PROTOTYPE[
190{]AT_PURE_IF([
191 YYUSE(lvalp);
192 YYUSE(llocp);], [AT_SKEL_CC_IF([
193 YYUSE(lvalp);
194 YYUSE(llocp);])])[
195 return 'x';
196}
197
198int
199main (void)
200{]AT_SKEL_CC_IF([[
6428a8a4 201 yy::parser p;
a1d1ab50
AD
202 p.set_debug_level (!!getenv("YYDEBUG"));
203 return p.parse ();]], [[
204 yydebug = !!getenv("YYDEBUG");
6428a8a4 205 return !!yyparse (]AT_PARAM_IF([0])[);]])[
a1d1ab50
AD
206}
207]])
208
209AT_FULL_COMPILE([input])
210AT_PARSER_CHECK([./input], 1, [],
fb4c8a7c
TR
211[m4_default([$4], [1.1])
212m4_default([$4], [1.1])[: syntax error
a1d1ab50
AD
213]])
214AT_BISON_OPTION_POPDEFS
215AT_CLEANUP
216])
217
218## FIXME: test Java, and iterate over skeletons.
219AT_TEST([yacc.c])
6428a8a4
TR
220AT_TEST([yacc.c], [%define api.pure full])
221AT_TEST([yacc.c], [%define api.pure %parse-param { int x }])
a1d1ab50 222AT_TEST([yacc.c], [%define api.push-pull both])
6428a8a4 223AT_TEST([yacc.c], [%define api.push-pull both %define api.pure full])
a1d1ab50 224AT_TEST([glr.c])
6428a8a4 225AT_TEST([glr.c], [%define api.pure])
a1d1ab50
AD
226AT_TEST([lalr1.cc])
227AT_TEST([glr.cc])
228
fb4c8a7c
TR
229## A very different test, based on PostgreSQL's implementation of the
230## locations. See
231## http://lists.gnu.org/archive/html/bug-bison/2012-11/msg00023.html
232##
233## Weirdly enough, to trigger the warning with GCC 4.7, we must not
234## use fprintf, so run the test twice: once to check the warning
235## (absence thereof), and another time to check the value.
6428a8a4 236AT_TEST([yacc.c], [%define api.pure full],
fb4c8a7c
TR
237[[%{
238# define YYLTYPE int
f0f95a50 239# define LOCATION_PRINT(Stream, Loc) \
fb4c8a7c
TR
240 (void) (Loc)
241# define YYLLOC_DEFAULT(Current, Rhs, N) \
242 (Current) = ((Rhs)[N ? 1 : 0])
243%}
244]],
245[@&t@])
246
6428a8a4 247AT_TEST([yacc.c], [%define api.pure full],
fb4c8a7c
TR
248[[%{
249# define YYLTYPE int
f0f95a50 250# define LOCATION_PRINT(Stream, Loc) \
fb4c8a7c
TR
251 fprintf ((Stream), "%d", (Loc))
252# define YYLLOC_DEFAULT(Current, Rhs, N) \
253 (Current) = ((Rhs)[N ? 1 : 0])
254%}
255]],
256[0])
257
258
a1d1ab50 259m4_popdef([AT_TEST])
75d1fe16 260
5dac0025
PE
261
262
3804aa26
AD
263## ---------------- ##
264## Location Print. ##
265## ---------------- ##
266
267# AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES], [LOCATION = 1.1])
268# -----------------------------------------------------------------------
269# Check that the initial location is correct.
270m4_pushdef([AT_TEST],
271[AT_SETUP([Location print: $1 $2])
272
273AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1" $2])
274AT_DATA_GRAMMAR([[input.y]],
66fb016e 275[[%locations
3804aa26
AD
276%debug
277%skeleton "$1"
278]$2[
279]$3[
280%code
281{
3804aa26
AD
282]AT_YYERROR_DECLARE[
283]AT_YYLEX_DECLARE[
284}
285%%
684083f0 286exp: %empty;
3804aa26
AD
287%%
288]AT_YYERROR_DEFINE[
289]AT_YYLEX_DEFINE[
290
291int
292main (void)
293{
aedcb6c0
AD
294 ]AT_YYLTYPE[ loc;
295]AT_GLR_CC_IF([loc.initialize();])[
3804aa26 296#define TEST(L1, C1, L2, C2) \
aedcb6c0
AD
297 loc.]AT_FIRST_LINE[ = L1; \
298 loc.]AT_FIRST_COLUMN[ = C1; \
299 loc.]AT_LAST_LINE[ = L2; \
300 loc.]AT_LAST_COLUMN[ = C2; \
301 ]AT_SKEL_CC_IF([std::cout << loc],
f0f95a50 302 [LOCATION_PRINT(stdout, loc)])[;\
3804aa26
AD
303 putchar ('\n');
304
305 TEST(1, 1, 1, 1);
306 TEST(2, 1, 2, 10);
307 TEST(3, 1, 4, 1);
308 TEST(5, 1, 6, 10);
309
310 TEST(7, 2, 0, 2);
311 TEST(8, 0, 8, 0);
1127a75a 312 return 0;
3804aa26
AD
313}
314]])
315
316AT_FULL_COMPILE([input])
317AT_PARSER_CHECK([./input], 0,
318[[1.1
3192.1-9
3203.1-4.0
3215.1-6.9
3227.2
3238.0
324]])
325AT_BISON_OPTION_POPDEFS
326AT_CLEANUP
327])
328
329## FIXME: test Java, and iterate over skeletons.
330AT_TEST([yacc.c])
331AT_TEST([glr.c])
aedcb6c0
AD
332AT_TEST([lalr1.cc])
333AT_TEST([glr.cc])
3804aa26
AD
334
335m4_popdef([AT_TEST])
336
337
338
75d1fe16
AD
339## ---------------- ##
340## Exotic Dollars. ##
341## ---------------- ##
342
343AT_SETUP([Exotic Dollars])
344
55f48c48 345AT_BISON_OPTION_PUSHDEFS
9501dc6e 346AT_DATA_GRAMMAR([[input.y]],
cf499cff 347[[%define parse.error verbose
8f3596a6 348%debug
f0f95a50 349%code {
55f48c48
AD
350]AT_YYERROR_DECLARE[
351]AT_YYLEX_DECLARE[
affac613 352# define USE(Var)
f0f95a50 353}
75d1fe16
AD
354
355%union
356{
357 int val;
358};
359
0ff67d71 360%type <val> a_1 a_2 a_5
378f4bd8 361 sum_of_the_five_previous_values
75d1fe16
AD
362
363%%
0ff67d71
PE
364exp: a_1 a_2 { $<val>$ = 3; } { $<val>$ = $<val>3 + 1; } a_5
365 sum_of_the_five_previous_values
75d1fe16 366 {
84866159 367 USE (($1, $2, $<foo>3, $<foo>4, $5));
75d1fe16
AD
368 printf ("%d\n", $6);
369 }
370;
371a_1: { $$ = 1; };
372a_2: { $$ = 2; };
75d1fe16
AD
373a_5: { $$ = 5; };
374
375sum_of_the_five_previous_values:
376 {
377 $$ = $<val>0 + $<val>-1 + $<val>-2 + $<val>-3 + $<val>-4;
378 }
379;
380
381%%
55f48c48 382]AT_YYERROR_DEFINE[
95361618 383]AT_YYLEX_DEFINE[
3ef9fa8f 384]AT_MAIN_DEFINE[
75d1fe16
AD
385]])
386
da730230 387AT_BISON_CHECK([-d -v -o input.c input.y], 0)
1154cced
AD
388AT_COMPILE([input])
389AT_PARSER_CHECK([./input], 0,
75d1fe16
AD
390[[15
391]])
392
82f3355e
JD
393# Make sure that fields after $n or $-n are parsed correctly. At one
394# point while implementing dashes in symbol names, we were dropping
395# fields after $-n.
396AT_DATA_GRAMMAR([[input.y]],
397[[
398%{
55f48c48
AD
399]AT_YYERROR_DECLARE[
400]AT_YYLEX_DECLARE[
82f3355e
JD
401 typedef struct { int val; } stype;
402# define YYSTYPE stype
403%}
404
405%%
406start: one two { $$.val = $1.val + $2.val; } sum ;
407one: { $$.val = 1; } ;
408two: { $$.val = 2; } ;
409sum: { printf ("%d\n", $0.val + $-1.val + $-2.val); } ;
410
411%%
55f48c48 412]AT_YYERROR_DEFINE[
95361618 413]AT_YYLEX_DEFINE[
3ef9fa8f 414]AT_MAIN_DEFINE[
82f3355e
JD
415]])
416
3112e7a8 417AT_FULL_COMPILE([input])
82f3355e
JD
418AT_PARSER_CHECK([[./input]], [[0]],
419[[6
420]])
421
55f48c48 422AT_BISON_OPTION_POPDEFS
75d1fe16 423AT_CLEANUP
9280d3ef
AD
424
425
426
e776192e
AD
427## -------------------------- ##
428## Printers and Destructors. ##
429## -------------------------- ##
9280d3ef 430
8d6c1b5e
AD
431# _AT_CHECK_PRINTER_AND_DESTRUCTOR($1, $2, $3, $4,
432# BISON-DIRECTIVE, UNION-FLAG)
433# -------------------------------------------------------------
3df37415 434m4_define([_AT_CHECK_PRINTER_AND_DESTRUCTOR],
9c66f418 435[# Make sure complex $n work.
8d6c1b5e 436m4_if([$1$2$3$4], $[1]$[2]$[3]$[4], [],
3df37415
AD
437 [m4_fatal([$0: Invalid arguments: $@])])dnl
438
9c66f418
AD
439# Be sure to pass all the %directives to this macro to have correct
440# helping macros. So don't put any directly in the Bison file.
c2729758 441AT_BISON_OPTION_PUSHDEFS([$5])
9501dc6e 442AT_DATA_GRAMMAR([[input.y]],
16dc6a9e 443[[%code requires {
9280d3ef
AD
444#include <stdio.h>
445#include <stdlib.h>
cf806753 446#include <string.h>
9c66f418 447#include <assert.h>
80ce3401
PE
448
449#define YYINITDEPTH 10
450#define YYMAXDEPTH 10
8d6c1b5e
AD
451#define RANGE(Location) ]AT_LALR1_CC_IF([(Location).begin.line, (Location).end.line],
452 [(Location).first_line, (Location).last_line])[
453
454/* Display the symbol type Symbol. */
455#define V(Symbol, Value, Location, Sep) \
456 fprintf (stderr, #Symbol " (%d@%d-%d)" Sep, Value, RANGE(Location))
457}
9c66f418 458
8d6c1b5e
AD
459$5
460]m4_ifval([$6], [%union
9280d3ef
AD
461{
462 int ival;
ac700aa6 463}])
16dc6a9e
JD
464AT_LALR1_CC_IF([%define global_tokens_and_yystype])
465m4_ifval([$6], [[%code provides {]], [[%code {]])
230a3db4
AD
466AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])[
467]AT_YYLEX_DECLARE[
55f48c48 468]AT_LALR1_CC_IF([], [AT_YYERROR_DECLARE])
9bc0dd67 469[}
c2729758 470
868d2d96 471]m4_ifval([$6], [%type <ival> '(' 'x' 'y' ')' ';' thing line input END])[
e3170060 472
868d2d96 473/* FIXME: This %printer isn't actually tested. */
a5eb1ed2
AD
474%printer
475 {
9a1e9989 476 ]AT_LALR1_CC_IF([debug_stream () << $$;],
3fc16193 477 [fprintf (yyoutput, "%d", $$)])[;
a5eb1ed2 478 }
9c66f418 479 input line thing 'x' 'y'
e3170060
AD
480
481%destructor
8d6c1b5e 482 { fprintf (stderr, "Freeing nterm input (%d@%d-%d)\n", $$, RANGE (@$)); }
7bd6c77e 483 input
5719c109 484
7bd6c77e 485%destructor
8d6c1b5e 486 { fprintf (stderr, "Freeing nterm line (%d@%d-%d)\n", $$, RANGE (@$)); }
7bd6c77e
AD
487 line
488
489%destructor
8d6c1b5e 490 { fprintf (stderr, "Freeing nterm thing (%d@%d-%d)\n", $$, RANGE (@$)); }
7bd6c77e
AD
491 thing
492
493%destructor
8d6c1b5e 494 { fprintf (stderr, "Freeing token 'x' (%d@%d-%d)\n", $$, RANGE (@$)); }
7bd6c77e 495 'x'
5719c109 496
9c66f418 497%destructor
8d6c1b5e 498 { fprintf (stderr, "Freeing token 'y' (%d@%d-%d)\n", $$, RANGE (@$)); }
9c66f418
AD
499 'y'
500
868d2d96
JD
501%token END 0
502%destructor
8d6c1b5e 503 { fprintf (stderr, "Freeing token END (%d@%d-%d)\n", $$, RANGE (@$)); }
868d2d96
JD
504 END
505
9280d3ef 506%%
9c66f418
AD
507/*
508 This grammar is made to exercise error recovery.
509 "Lines" starting with `(' support error recovery, with
510 ')' as synchronizing token. Lines starting with 'x' can never
511 be recovered from if in error.
512*/
513
9280d3ef
AD
514input:
515 /* Nothing. */
5719c109
AD
516 {
517 $$ = 0;
8d6c1b5e 518 V(input, $$, @$, ": /* Nothing */\n");
5719c109
AD
519 }
520| line input /* Right recursive to load the stack so that popping at
e9690142 521 END can be exercised. */
5719c109
AD
522 {
523 $$ = 2;
8d6c1b5e
AD
524 V(input, $$, @$, ": ");
525 V(line, $1, @1, " ");
526 V(input, $2, @2, "\n");
5719c109 527 }
9280d3ef
AD
528;
529
530line:
531 thing thing thing ';'
5719c109
AD
532 {
533 $$ = $1;
8d6c1b5e
AD
534 V(line, $$, @$, ": ");
535 V(thing, $1, @1, " ");
536 V(thing, $2, @2, " ");
537 V(thing, $3, @3, " ");
538 V(;, $4, @4, "\n");
5719c109 539 }
9c66f418 540| '(' thing thing ')'
5719c109
AD
541 {
542 $$ = $1;
8d6c1b5e
AD
543 V(line, $$, @$, ": ");
544 V('(', $1, @1, " ");
545 V(thing, $2, @2, " ");
546 V(thing, $3, @3, " ");
547 V(')', $4, @4, "\n");
5719c109 548 }
9c66f418 549| '(' thing ')'
5719c109
AD
550 {
551 $$ = $1;
8d6c1b5e
AD
552 V(line, $$, @$, ": ");
553 V('(', $1, @1, " ");
554 V(thing, $2, @2, " ");
555 V(')', $3, @3, "\n");
5719c109 556 }
9c66f418 557| '(' error ')'
5719c109
AD
558 {
559 $$ = -1;
8d6c1b5e
AD
560 V(line, $$, @$, ": ");
561 V('(', $1, @1, " ");
562 fprintf (stderr, "error (@%d-%d) ", RANGE(@2));
563 V(')', $3, @3, "\n");
5719c109 564 }
9280d3ef
AD
565;
566
567thing:
5719c109
AD
568 'x'
569 {
570 $$ = $1;
8d6c1b5e
AD
571 V(thing, $$, @$, ": ");
572 V('x', $1, @1, "\n");
5719c109 573 }
9280d3ef
AD
574;
575%%
9c66f418 576/* Alias to ARGV[1]. */
ef51bfa7 577const char *source = YY_NULL;
9c66f418 578
8d6c1b5e
AD
579]AT_YYERROR_DEFINE[
580
230a3db4
AD
581static
582]AT_YYLEX_PROTOTYPE[
9280d3ef 583{
5a08f1ce 584 static unsigned int counter = 0;
9280d3ef 585
9c66f418
AD
586 int c = ]AT_VAL[]m4_ifval([$6], [.ival])[ = counter++;
587 /* As in BASIC, line numbers go from 10 to 10. */
8d6c1b5e
AD
588 ]AT_LOC_FIRST_LINE[ = ]AT_LOC_FIRST_COLUMN[ = 10 * c;
589 ]AT_LOC_LAST_LINE[ = ]AT_LOC_LAST_COLUMN[ = ]AT_LOC_FIRST_LINE[ + 9;
77519a7d 590 assert (0 <= c && c <= strlen (source));
a9739e7c 591 if (source[c])
8d6c1b5e 592 fprintf (stderr, "sending: '%c'", source[c]);
9280d3ef 593 else
8d6c1b5e
AD
594 fprintf (stderr, "sending: END");
595 fprintf (stderr, " (%d@%d-%d)\n", c, RANGE (]AT_LOC[));
a9739e7c 596 return source[c];
9280d3ef 597}
c2729758 598]AT_LALR1_CC_IF(
8d6c1b5e 599[static bool yydebug;
c2729758
ADL
600int
601yyparse ()
602{
99880de5 603 yy::parser parser;
a3cb6248 604 parser.set_debug_level (yydebug);
c2729758
ADL
605 return parser.parse ();
606}
8d6c1b5e 607])[
9280d3ef 608
9280d3ef 609int
9c66f418 610main (int argc, const char *argv[])
9280d3ef 611{
6100a9aa 612 int status;
9280d3ef 613 yydebug = !!getenv ("YYDEBUG");
9c66f418 614 assert (argc == 2);
a9739e7c 615 source = argv[1];
6100a9aa
PE
616 status = yyparse ();
617 switch (status)
9280d3ef 618 {
8d6c1b5e
AD
619 case 0: fprintf (stderr, "Successful parse.\n"); break;
620 case 1: fprintf (stderr, "Parsing FAILED.\n"); break;
621 default: fprintf (stderr, "Parsing FAILED (status %d).\n", status); break;
9280d3ef 622 }
6100a9aa 623 return status;
9280d3ef
AD
624}
625]])
626
7ca2266a 627AT_FULL_COMPILE([input])
9c66f418
AD
628
629
630# Check the location of "empty"
631# -----------------------------
632# I.e., epsilon-reductions, as in "(x)" which ends by reducing
633# an empty "line" nterm.
634# FIXME: This location is not satisfying. Depend on the lookahead?
8d6c1b5e 635AT_PARSER_CHECK([./input '(x)'], 0, [],
9c66f418
AD
636[[sending: '(' (0@0-9)
637sending: 'x' (1@10-19)
638thing (1@10-19): 'x' (1@10-19)
639sending: ')' (2@20-29)
640line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29)
868d2d96 641sending: END (3@30-39)
b4a20338
AD
642input (0@29-29): /* Nothing */
643input (2@0-29): line (0@0-29) input (0@29-29)
868d2d96 644Freeing token END (3@30-39)
258b75ca 645Freeing nterm input (2@0-29)
9c66f418
AD
646Successful parse.
647]])
648
649
650# Check locations in error recovery
651# ---------------------------------
652# '(y)' is an error, but can be recovered from. But what's the location
653# of the error itself ('y'), and of the resulting reduction ('(error)').
8d6c1b5e 654AT_PARSER_CHECK([./input '(y)'], 0, [],
9c66f418
AD
655[[sending: '(' (0@0-9)
656sending: 'y' (1@10-19)
8d6c1b5e 65710.10-19.18: syntax error, unexpected 'y', expecting 'x'
9c66f418
AD
658Freeing token 'y' (1@10-19)
659sending: ')' (2@20-29)
660line (-1@0-29): '(' (0@0-9) error (@10-19) ')' (2@20-29)
868d2d96 661sending: END (3@30-39)
b4a20338
AD
662input (0@29-29): /* Nothing */
663input (2@0-29): line (-1@0-29) input (0@29-29)
868d2d96 664Freeing token END (3@30-39)
258b75ca 665Freeing nterm input (2@0-29)
9c66f418
AD
666Successful parse.
667]])
668
669
670# Syntax errors caught by the parser
671# ----------------------------------
672# Exercise the discarding of stack top and input until `error'
673# can be reduced.
674#
675# '(', 'x', 'x', 'x', 'x', 'x', ')',
676#
677# Load the stack and provoke an error that cannot be caught by the
678# grammar, to check that the stack is cleared. And make sure the
679# lookahead is freed.
680#
681# '(', 'x', ')',
682# '(', 'x', ')',
683# 'y'
8d6c1b5e 684AT_PARSER_CHECK([./input '(xxxxx)(x)(x)y'], 1, [],
9c66f418 685[[sending: '(' (0@0-9)
4c6cc1db
AD
686sending: 'x' (1@10-19)
687thing (1@10-19): 'x' (1@10-19)
688sending: 'x' (2@20-29)
689thing (2@20-29): 'x' (2@20-29)
690sending: 'x' (3@30-39)
8d6c1b5e 69130.30-39.38: syntax error, unexpected 'x', expecting ')'
4c6cc1db
AD
692Freeing nterm thing (2@20-29)
693Freeing nterm thing (1@10-19)
4c6cc1db
AD
694Freeing token 'x' (3@30-39)
695sending: 'x' (4@40-49)
696Freeing token 'x' (4@40-49)
697sending: 'x' (5@50-59)
698Freeing token 'x' (5@50-59)
9c66f418
AD
699sending: ')' (6@60-69)
700line (-1@0-69): '(' (0@0-9) error (@10-59) ')' (6@60-69)
701sending: '(' (7@70-79)
4c6cc1db
AD
702sending: 'x' (8@80-89)
703thing (8@80-89): 'x' (8@80-89)
9c66f418
AD
704sending: ')' (9@90-99)
705line (7@70-99): '(' (7@70-79) thing (8@80-89) ')' (9@90-99)
706sending: '(' (10@100-109)
707sending: 'x' (11@110-119)
708thing (11@110-119): 'x' (11@110-119)
709sending: ')' (12@120-129)
710line (10@100-129): '(' (10@100-109) thing (11@110-119) ')' (12@120-129)
711sending: 'y' (13@130-139)
b4a20338
AD
712input (0@129-129): /* Nothing */
713input (2@100-129): line (10@100-129) input (0@129-129)
9c66f418
AD
714input (2@70-129): line (7@70-99) input (2@100-129)
715input (2@0-129): line (-1@0-69) input (2@70-129)
8d6c1b5e 716130.130-139.138: syntax error, unexpected 'y', expecting END
9c66f418
AD
717Freeing nterm input (2@0-129)
718Freeing token 'y' (13@130-139)
5719c109 719Parsing FAILED.
9280d3ef
AD
720]])
721
868d2d96
JD
722
723# Syntax error caught by the parser where lookahead = END
724# --------------------------------------------------------
725# Load the stack and provoke an error that cannot be caught by the
726# grammar, to check that the stack is cleared. And make sure the
727# lookahead is freed.
728#
729# '(', 'x', ')',
730# '(', 'x', ')',
731# 'x'
8d6c1b5e 732AT_PARSER_CHECK([./input '(x)(x)x'], 1, [],
868d2d96
JD
733[[sending: '(' (0@0-9)
734sending: 'x' (1@10-19)
735thing (1@10-19): 'x' (1@10-19)
736sending: ')' (2@20-29)
737line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29)
738sending: '(' (3@30-39)
739sending: 'x' (4@40-49)
740thing (4@40-49): 'x' (4@40-49)
741sending: ')' (5@50-59)
742line (3@30-59): '(' (3@30-39) thing (4@40-49) ')' (5@50-59)
743sending: 'x' (6@60-69)
744thing (6@60-69): 'x' (6@60-69)
745sending: END (7@70-79)
8d6c1b5e 74670.70-79.78: syntax error, unexpected END, expecting 'x'
868d2d96
JD
747Freeing nterm thing (6@60-69)
748Freeing nterm line (3@30-59)
749Freeing nterm line (0@0-29)
750Freeing token END (7@70-79)
751Parsing FAILED.
752]])
753
754
80ce3401
PE
755# Check destruction upon stack overflow
756# -------------------------------------
757# Upon stack overflow, all symbols on the stack should be destroyed.
758# Only check for yacc.c.
759AT_YACC_IF([
8d6c1b5e 760AT_PARSER_CHECK([./input '(x)(x)(x)(x)(x)(x)(x)'], 2, [],
80ce3401
PE
761[[sending: '(' (0@0-9)
762sending: 'x' (1@10-19)
763thing (1@10-19): 'x' (1@10-19)
764sending: ')' (2@20-29)
765line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29)
766sending: '(' (3@30-39)
767sending: 'x' (4@40-49)
768thing (4@40-49): 'x' (4@40-49)
769sending: ')' (5@50-59)
770line (3@30-59): '(' (3@30-39) thing (4@40-49) ')' (5@50-59)
771sending: '(' (6@60-69)
772sending: 'x' (7@70-79)
773thing (7@70-79): 'x' (7@70-79)
774sending: ')' (8@80-89)
775line (6@60-89): '(' (6@60-69) thing (7@70-79) ')' (8@80-89)
776sending: '(' (9@90-99)
777sending: 'x' (10@100-109)
778thing (10@100-109): 'x' (10@100-109)
779sending: ')' (11@110-119)
780line (9@90-119): '(' (9@90-99) thing (10@100-109) ')' (11@110-119)
781sending: '(' (12@120-129)
782sending: 'x' (13@130-139)
783thing (13@130-139): 'x' (13@130-139)
784sending: ')' (14@140-149)
785line (12@120-149): '(' (12@120-129) thing (13@130-139) ')' (14@140-149)
786sending: '(' (15@150-159)
787sending: 'x' (16@160-169)
788thing (16@160-169): 'x' (16@160-169)
789sending: ')' (17@170-179)
790line (15@150-179): '(' (15@150-159) thing (16@160-169) ')' (17@170-179)
791sending: '(' (18@180-189)
792sending: 'x' (19@190-199)
793thing (19@190-199): 'x' (19@190-199)
794sending: ')' (20@200-209)
8d6c1b5e 795200.200-209.208: memory exhausted
80ce3401
PE
796Freeing nterm thing (19@190-199)
797Freeing nterm line (15@150-179)
798Freeing nterm line (12@120-149)
799Freeing nterm line (9@90-119)
800Freeing nterm line (6@60-89)
801Freeing nterm line (3@30-59)
802Freeing nterm line (0@0-29)
6100a9aa 803Parsing FAILED (status 2).
80ce3401
PE
804]])
805])
806
55f48c48
AD
807AT_BISON_OPTION_POPDEFS
808])# _AT_CHECK_PRINTER_AND_DESTRUCTOR
3df37415
AD
809
810
a14a26fa 811# AT_CHECK_PRINTER_AND_DESTRUCTOR([BISON-OPTIONS], [UNION-FLAG], [SKIP_FLAG])
046ac74e 812# ---------------------------------------------------------------------------
3df37415 813m4_define([AT_CHECK_PRINTER_AND_DESTRUCTOR],
623a5147 814[AT_SETUP([Printers and Destructors$2]m4_ifval([$1], [[: $1]]))
9c66f418 815
a14a26fa 816$3
9c66f418 817_AT_CHECK_PRINTER_AND_DESTRUCTOR($[1], $[2], $[3], $[4],
cf499cff 818[%define parse.error verbose
9c66f418
AD
819%debug
820%verbose
821%locations
822$1], [$2])
823
824AT_CLEANUP
3df37415
AD
825])
826
827
ac700aa6
PE
828AT_CHECK_PRINTER_AND_DESTRUCTOR([])
829AT_CHECK_PRINTER_AND_DESTRUCTOR([], [with union])
046ac74e 830
fd19f271
AD
831AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"])
832AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [with union])
046ac74e 833
1576d44d
AD
834AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser])
835AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [with union])
ec5479ce
JD
836
837
838
12e35840
JD
839## ----------------------------------------- ##
840## Default tagless %printer and %destructor. ##
841## ----------------------------------------- ##
ec5479ce
JD
842
843# Check that the right %printer and %destructor are called, that they're not
844# called for $end, and that $$ and @$ work correctly.
845
12e35840 846AT_SETUP([Default tagless %printer and %destructor])
f42c012f 847AT_BISON_OPTION_PUSHDEFS([%locations %debug])
ec5479ce 848AT_DATA_GRAMMAR([[input.y]],
cf499cff 849[[%define parse.error verbose
ec5479ce
JD
850%debug
851%locations
ec5479ce 852
f0f95a50 853%code {
55f48c48
AD
854]AT_YYLEX_DECLARE[
855]AT_YYERROR_DECLARE[
ec5479ce 856# define USE(SYM)
f0f95a50 857}
ec5479ce
JD
858
859%printer {
12e35840
JD
860 fprintf (yyoutput, "<*> printer should not be called.\n");
861} <*>
862
863%printer {
3ebecc24
JD
864 fprintf (yyoutput, "<> printer for '%c' @ %d", $$, @$.first_column);
865} <>
ec5479ce 866%destructor {
3ebecc24
JD
867 fprintf (stdout, "<> destructor for '%c' @ %d.\n", $$, @$.first_column);
868} <>
ec5479ce
JD
869
870%printer {
871 fprintf (yyoutput, "'b'/'c' printer for '%c' @ %d", $$, @$.first_column);
872} 'b' 'c'
873%destructor {
874 fprintf (stdout, "'b'/'c' destructor for '%c' @ %d.\n", $$, @$.first_column);
875} 'b' 'c'
876
12e35840
JD
877%destructor {
878 fprintf (yyoutput, "<*> destructor should not be called.\n");
879} <*>
880
ec5479ce
JD
881%%
882
883start: 'a' 'b' 'c' 'd' 'e' { $$ = 'S'; USE(($1, $2, $3, $4, $5)); } ;
884
885%%
55f48c48 886]AT_YYERROR_DEFINE[
95361618 887]AT_YYLEX_DEFINE(["abcd"], [[yylval = res]])[
f42c012f 888]AT_MAIN_DEFINE[
ec5479ce
JD
889]])
890
9534d2be 891AT_BISON_CHECK([-o input.c input.y], [], [],
f0f95a50
AD
892[[input.y:30.3-5: warning: useless %destructor for type <*> [-Wother]
893input.y:30.3-5: warning: useless %printer for type <*> [-Wother]
9534d2be 894]])
ec5479ce 895AT_COMPILE([input])
f42c012f 896AT_PARSER_CHECK([./input --debug], 1,
3ebecc24 897[[<> destructor for 'd' @ 4.
ec5479ce
JD
898'b'/'c' destructor for 'c' @ 3.
899'b'/'c' destructor for 'b' @ 2.
3ebecc24 900<> destructor for 'a' @ 1.
ec5479ce
JD
901]],
902[[Starting parse
903Entering state 0
3237f570
AD
904Reading a token: Next token is token 'a' (1.1: <> printer for 'a' @ 1)
905Shifting token 'a' (1.1: <> printer for 'a' @ 1)
ec5479ce 906Entering state 1
3237f570
AD
907Reading a token: Next token is token 'b' (1.2: 'b'/'c' printer for 'b' @ 2)
908Shifting token 'b' (1.2: 'b'/'c' printer for 'b' @ 2)
ec5479ce 909Entering state 3
3237f570
AD
910Reading a token: Next token is token 'c' (1.3: 'b'/'c' printer for 'c' @ 3)
911Shifting token 'c' (1.3: 'b'/'c' printer for 'c' @ 3)
ec5479ce 912Entering state 5
3237f570
AD
913Reading a token: Next token is token 'd' (1.4: <> printer for 'd' @ 4)
914Shifting token 'd' (1.4: <> printer for 'd' @ 4)
ec5479ce
JD
915Entering state 6
916Reading a token: Now at end of input.
7dbb8d8a 9171.5: syntax error, unexpected $end, expecting 'e'
3237f570 918Error: popping token 'd' (1.4: <> printer for 'd' @ 4)
ec5479ce 919Stack now 0 1 3 5
3237f570 920Error: popping token 'c' (1.3: 'b'/'c' printer for 'c' @ 3)
ec5479ce 921Stack now 0 1 3
3237f570 922Error: popping token 'b' (1.2: 'b'/'c' printer for 'b' @ 2)
ec5479ce 923Stack now 0 1
3237f570 924Error: popping token 'a' (1.1: <> printer for 'a' @ 1)
ec5479ce 925Stack now 0
3237f570 926Cleanup: discarding lookahead token $end (1.5: )
ec5479ce
JD
927Stack now 0
928]])
929
55f48c48 930AT_BISON_OPTION_POPDEFS
ec5479ce
JD
931AT_CLEANUP
932
933
934
12e35840
JD
935## ------------------------------------------------------ ##
936## Default tagged and per-type %printer and %destructor. ##
937## ------------------------------------------------------ ##
b2a0b7ca 938
12e35840 939AT_SETUP([Default tagged and per-type %printer and %destructor])
f42c012f 940AT_BISON_OPTION_PUSHDEFS([%debug])
b2a0b7ca 941AT_DATA_GRAMMAR([[input.y]],
cf499cff 942[[%define parse.error verbose
b2a0b7ca
JD
943%debug
944
945%{
55f48c48
AD
946]AT_YYERROR_DECLARE[
947]AT_YYLEX_DECLARE[
b2a0b7ca
JD
948# define USE(SYM)
949%}
950
12e35840 951%printer {
3ebecc24
JD
952 fprintf (yyoutput, "<> printer should not be called.\n");
953} <>
12e35840 954
b2a0b7ca
JD
955%union { int field0; int field1; int field2; }
956%type <field0> start 'a' 'g'
957%type <field1> 'e'
958%type <field2> 'f'
959%printer {
12e35840
JD
960 fprintf (yyoutput, "<*>/<field2>/e printer");
961} <*> 'e' <field2>
b2a0b7ca 962%destructor {
12e35840
JD
963 fprintf (stdout, "<*>/<field2>/e destructor.\n");
964} <*> 'e' <field2>
b2a0b7ca
JD
965
966%type <field1> 'b'
967%printer { fprintf (yyoutput, "<field1> printer"); } <field1>
968%destructor { fprintf (stdout, "<field1> destructor.\n"); } <field1>
969
970%type <field0> 'c'
971%printer { fprintf (yyoutput, "'c' printer"); } 'c'
972%destructor { fprintf (stdout, "'c' destructor.\n"); } 'c'
973
974%type <field1> 'd'
975%printer { fprintf (yyoutput, "'d' printer"); } 'd'
976%destructor { fprintf (stdout, "'d' destructor.\n"); } 'd'
977
12e35840 978%destructor {
3ebecc24
JD
979 fprintf (yyoutput, "<> destructor should not be called.\n");
980} <>
12e35840 981
b2a0b7ca
JD
982%%
983
984start:
985 'a' 'b' 'c' 'd' 'e' 'f' 'g'
986 {
987 USE(($1, $2, $3, $4, $5, $6, $7));
988 $$ = 'S';
989 }
990 ;
991
992%%
55f48c48 993]AT_YYERROR_DEFINE[
95361618 994]AT_YYLEX_DEFINE(["abcdef"])[
f42c012f 995]AT_MAIN_DEFINE[
b2a0b7ca
JD
996]])
997
9534d2be
AD
998AT_BISON_CHECK([-o input.c input.y], [], [],
999[[input.y:22.3-4: warning: useless %destructor for type <> [-Wother]
1000input.y:22.3-4: warning: useless %printer for type <> [-Wother]
1001]])
b2a0b7ca 1002AT_COMPILE([input])
f42c012f 1003AT_PARSER_CHECK([./input --debug], 1,
12e35840
JD
1004[[<*>/<field2>/e destructor.
1005<*>/<field2>/e destructor.
b2a0b7ca
JD
1006'd' destructor.
1007'c' destructor.
1008<field1> destructor.
12e35840 1009<*>/<field2>/e destructor.
b2a0b7ca
JD
1010]],
1011[[Starting parse
1012Entering state 0
12e35840
JD
1013Reading a token: Next token is token 'a' (<*>/<field2>/e printer)
1014Shifting token 'a' (<*>/<field2>/e printer)
b2a0b7ca
JD
1015Entering state 1
1016Reading a token: Next token is token 'b' (<field1> printer)
1017Shifting token 'b' (<field1> printer)
1018Entering state 3
1019Reading a token: Next token is token 'c' ('c' printer)
1020Shifting token 'c' ('c' printer)
1021Entering state 5
1022Reading a token: Next token is token 'd' ('d' printer)
1023Shifting token 'd' ('d' printer)
1024Entering state 6
12e35840
JD
1025Reading a token: Next token is token 'e' (<*>/<field2>/e printer)
1026Shifting token 'e' (<*>/<field2>/e printer)
b2a0b7ca 1027Entering state 7
12e35840
JD
1028Reading a token: Next token is token 'f' (<*>/<field2>/e printer)
1029Shifting token 'f' (<*>/<field2>/e printer)
b2a0b7ca
JD
1030Entering state 8
1031Reading a token: Now at end of input.
1032syntax error, unexpected $end, expecting 'g'
12e35840 1033Error: popping token 'f' (<*>/<field2>/e printer)
b2a0b7ca 1034Stack now 0 1 3 5 6 7
12e35840 1035Error: popping token 'e' (<*>/<field2>/e printer)
b2a0b7ca
JD
1036Stack now 0 1 3 5 6
1037Error: popping token 'd' ('d' printer)
1038Stack now 0 1 3 5
1039Error: popping token 'c' ('c' printer)
1040Stack now 0 1 3
1041Error: popping token 'b' (<field1> printer)
1042Stack now 0 1
12e35840 1043Error: popping token 'a' (<*>/<field2>/e printer)
b2a0b7ca
JD
1044Stack now 0
1045Cleanup: discarding lookahead token $end ()
1046Stack now 0
1047]])
1048
55f48c48 1049AT_BISON_OPTION_POPDEFS
b2a0b7ca
JD
1050AT_CLEANUP
1051
1052
1053
ec5479ce 1054## ------------------------------------------------------------- ##
12e35840 1055## Default %printer and %destructor for user-defined end token. ##
ec5479ce
JD
1056## ------------------------------------------------------------- ##
1057
3508ce36 1058AT_SETUP([Default %printer and %destructor for user-defined end token])
ec5479ce 1059
9534d2be
AD
1060# AT_TEST(TYPED)
1061# --------------
1062m4_pushdef([AT_TEST],
12e35840 1063[m4_if($1, 0,
3ebecc24
JD
1064 [m4_pushdef([kind], []) m4_pushdef([not_kind], [*])],
1065 [m4_pushdef([kind], [*]) m4_pushdef([not_kind], [])])
12e35840 1066
f42c012f 1067AT_BISON_OPTION_PUSHDEFS([%locations %debug])
12e35840 1068AT_DATA_GRAMMAR([[input]]$1[[.y]],
cf499cff 1069[[%define parse.error verbose
ec5479ce
JD
1070%debug
1071%locations
ec5479ce 1072
f0f95a50 1073%code {
55f48c48
AD
1074]AT_YYERROR_DECLARE[
1075]AT_YYLEX_DECLARE[
ec5479ce 1076# define USE(SYM)
f0f95a50 1077}
ec5479ce 1078
12e35840
JD
1079%destructor {
1080 fprintf (yyoutput, "<]]not_kind[[> destructor should not be called.\n");
1081} <]]not_kind[[>
1082
ec5479ce
JD
1083%token END 0
1084%printer {
12e35840
JD
1085 fprintf (yyoutput, "<]]kind[[> for '%c' @ %d", $$, @$.first_column);
1086} <]]kind[[>
ec5479ce 1087%destructor {
12e35840
JD
1088 fprintf (stdout, "<]]kind[[> for '%c' @ %d.\n", $$, @$.first_column);
1089} <]]kind[[>
1090
1091%printer {
1092 fprintf (yyoutput, "<]]not_kind[[> printer should not be called.\n");
1093} <]]not_kind[[>
1094
1095]]m4_if($1, 0, [[[
1096]]],
1097[[[%union { char tag; }
1098%type <tag> start END]]])[[
ec5479ce
JD
1099
1100%%
1101
1102start: { $$ = 'S'; } ;
1103
1104%%
312c0cff 1105#include <stdlib.h> /* abort */
ec5479ce
JD
1106static int
1107yylex (void)
1108{
cf806753
PE
1109 static int called;
1110 if (called++)
1111 abort ();
12e35840 1112 yylval]]m4_if($1, 0,, [[[.tag]]])[[ = 'E';
ec5479ce
JD
1113 yylloc.first_line = yylloc.last_line = 1;
1114 yylloc.first_column = yylloc.last_column = 1;
1115 return 0;
1116}
55f48c48 1117]AT_YYERROR_DEFINE[
f42c012f 1118]AT_MAIN_DEFINE[
ec5479ce 1119]])
55f48c48 1120AT_BISON_OPTION_POPDEFS
ec5479ce 1121
9534d2be
AD
1122AT_BISON_CHECK([-o input$1.c input$1.y], [], [],
1123[m4_if([$1], [0],
f0f95a50
AD
1124[[input0.y:30.3-5: warning: useless %destructor for type <*> [-Wother]
1125input0.y:30.3-5: warning: useless %printer for type <*> [-Wother]
9534d2be 1126]],
f0f95a50
AD
1127[[input1.y:30.3-4: warning: useless %destructor for type <> [-Wother]
1128input1.y:30.3-4: warning: useless %printer for type <> [-Wother]
9534d2be
AD
1129]])])
1130
12e35840 1131AT_COMPILE([input$1])
9534d2be 1132
f42c012f 1133AT_PARSER_CHECK([./input$1 --debug], 0,
12e35840
JD
1134[[<]]kind[[> for 'E' @ 1.
1135<]]kind[[> for 'S' @ 1.
ec5479ce
JD
1136]],
1137[[Starting parse
1138Entering state 0
f0f95a50 1139Reducing stack by rule 1 (line 49):
3237f570 1140-> $$ = nterm start (1.1: <]]kind[[> for 'S' @ 1)
ec5479ce
JD
1141Stack now 0
1142Entering state 1
1143Reading a token: Now at end of input.
3237f570 1144Shifting token END (1.1: <]]kind[[> for 'E' @ 1)
ec5479ce
JD
1145Entering state 2
1146Stack now 0 1 2
3237f570
AD
1147Cleanup: popping token END (1.1: <]]kind[[> for 'E' @ 1)
1148Cleanup: popping nterm start (1.1: <]]kind[[> for 'S' @ 1)
ec5479ce
JD
1149]])
1150
12e35840
JD
1151m4_popdef([kind])
1152m4_popdef([not_kind])
1153])
1154
9534d2be
AD
1155AT_TEST(0)
1156AT_TEST(1)
1157
1158m4_popdef([AT_TEST])
12e35840 1159
ec5479ce 1160AT_CLEANUP
9350499c
JD
1161
1162
1163
1164## ------------------------------------------------------------------ ##
1165## Default %printer and %destructor are not for error or $undefined. ##
1166## ------------------------------------------------------------------ ##
1167
287b314e 1168AT_SETUP([Default %printer and %destructor are not for error or $undefined])
9350499c
JD
1169
1170# If Bison were to apply the default %printer and %destructor to the error
1171# token or to $undefined:
1172# - For the error token:
1173# - It would generate warnings for unused $n.
1174# - It would invoke the %printer and %destructor on the error token's
1175# semantic value, which would be initialized from the lookahead, which
1176# would be destroyed separately.
1177# - For $undefined, who knows what the semantic value would be.
f42c012f 1178AT_BISON_OPTION_PUSHDEFS([%debug])
9350499c
JD
1179AT_DATA_GRAMMAR([[input.y]],
1180[[%debug
1181
1182%{
1183# include <stdio.h>
cf806753 1184# include <stdlib.h>
55f48c48
AD
1185]AT_YYERROR_DECLARE[
1186]AT_YYLEX_DECLARE[
9350499c
JD
1187# define USE(SYM)
1188%}
1189
1190%printer {
1191 fprintf (yyoutput, "'%c'", $$);
3ebecc24 1192} <> <*>
9350499c
JD
1193%destructor {
1194 fprintf (stderr, "DESTROY '%c'\n", $$);
3ebecc24 1195} <> <*>
9350499c
JD
1196
1197%%
1198
1199start:
1200 { $$ = 'S'; }
1201 /* In order to reveal the problems that this bug caused during parsing, add
1202 * $2 to USE. */
1203 | 'a' error 'b' 'c' { USE(($1, $3, $4)); $$ = 'S'; }
1204 ;
1205
1206%%
55f48c48 1207]AT_YYERROR_DEFINE[
95361618 1208]AT_YYLEX_DEFINE(["abd"], [yylval = res])[
f42c012f 1209]AT_MAIN_DEFINE[
9350499c 1210]])
55f48c48 1211AT_BISON_OPTION_POPDEFS
9350499c 1212
9534d2be 1213AT_BISON_CHECK([-o input.c input.y], [], [],
f0f95a50
AD
1214[[input.y:23.6-8: warning: useless %destructor for type <*> [-Wother]
1215input.y:23.6-8: warning: useless %printer for type <*> [-Wother]
9534d2be 1216]])
9350499c 1217AT_COMPILE([input])
f42c012f 1218AT_PARSER_CHECK([./input --debug], [1], [],
9350499c
JD
1219[[Starting parse
1220Entering state 0
1221Reading a token: Next token is token 'a' ('a')
1222Shifting token 'a' ('a')
1223Entering state 1
1224Reading a token: Next token is token 'b' ('b')
1225syntax error
1226Shifting token error ()
1227Entering state 3
1228Next token is token 'b' ('b')
1229Shifting token 'b' ('b')
1230Entering state 5
1231Reading a token: Next token is token $undefined ()
1232Error: popping token 'b' ('b')
1233DESTROY 'b'
1234Stack now 0 1 3
1235Error: popping token error ()
1236Stack now 0 1
1237Shifting token error ()
1238Entering state 3
1239Next token is token $undefined ()
1240Error: discarding token $undefined ()
1241Error: popping token error ()
1242Stack now 0 1
1243Shifting token error ()
1244Entering state 3
1245Reading a token: Now at end of input.
1246Cleanup: discarding lookahead token $end ()
1247Stack now 0 1 3
1248Cleanup: popping token error ()
1249Cleanup: popping token 'a' ('a')
1250DESTROY 'a'
1251]])
1252
1253AT_CLEANUP
1254
1255
1256
1257## ------------------------------------------------------ ##
1258## Default %printer and %destructor are not for $accept. ##
1259## ------------------------------------------------------ ##
1260
287b314e 1261AT_SETUP([Default %printer and %destructor are not for $accept])
9350499c
JD
1262
1263# If YYSTYPE is a union and Bison were to apply the default %printer and
1264# %destructor to $accept:
1265# - The %printer and %destructor code generated for $accept would always be
1266# dead code because $accept is currently never shifted onto the stack.
1267# - $$ for $accept would always be of type YYSTYPE because it's not possible
1268# to declare `%type <field> $accept'. (Also true for $undefined.)
1269# - Thus, the compiler might complain that the user code assumes the wrong
1270# type for $$ since the code might assume the type associated with a
1271# specific union field, which is especially reasonable in C++ since that
1272# type may be a base type. This test case checks for this problem. (Also
1273# true for $undefined and the error token, so there are three warnings for
1274# %printer and three for %destructor.)
1275
f42c012f 1276AT_BISON_OPTION_PUSHDEFS([%debug])
9350499c
JD
1277AT_DATA_GRAMMAR([[input.y]],
1278[[%debug /* So that %printer is actually compiled. */
1279
1280%{
1281# include <stdio.h>
cf806753 1282# include <stdlib.h>
55f48c48
AD
1283]AT_YYERROR_DECLARE[
1284]AT_YYLEX_DECLARE[
9350499c
JD
1285# define USE(SYM)
1286%}
1287
1288%printer {
1289 char chr = $$;
1290 fprintf (yyoutput, "'%c'", chr);
3ebecc24 1291} <> <*>
9350499c
JD
1292%destructor {
1293 char chr = $$;
1294 fprintf (stderr, "DESTROY '%c'\n", chr);
3ebecc24 1295} <> <*>
9350499c
JD
1296
1297%union { char chr; }
1298%type <chr> start
1299
1300%%
1301
1302start: { USE($$); } ;
1303
1304%%
55f48c48 1305]AT_YYERROR_DEFINE[
95361618 1306]AT_YYLEX_DEFINE[
3ef9fa8f 1307]AT_MAIN_DEFINE[
9350499c 1308]])
55f48c48 1309AT_BISON_OPTION_POPDEFS
9350499c 1310
9534d2be 1311AT_BISON_CHECK([-o input.c input.y], [], [],
f0f95a50
AD
1312[[input.y:24.3-4: warning: useless %destructor for type <> [-Wother]
1313input.y:24.3-4: warning: useless %printer for type <> [-Wother]
9534d2be 1314]])
9350499c
JD
1315AT_COMPILE([input])
1316
1317AT_CLEANUP
f91b1629
JD
1318
1319
1320
1321## ------------------------------------------------------ ##
1322## Default %printer and %destructor for mid-rule values. ##
1323## ------------------------------------------------------ ##
1324
1325AT_SETUP([Default %printer and %destructor for mid-rule values])
1326
f42c012f 1327AT_BISON_OPTION_PUSHDEFS([%debug])
f91b1629
JD
1328AT_DATA_GRAMMAR([[input.y]],
1329[[%debug /* So that %printer is actually compiled. */
1330
1331%{
55f48c48
AD
1332]AT_YYERROR_DECLARE[
1333]AT_YYLEX_DECLARE[
f91b1629
JD
1334# define USE(SYM)
1335# define YYLTYPE int
9fc4c025 1336# define YYLLOC_DEFAULT(Current, Rhs, N) (void)(Rhs)
f0f95a50 1337# define LOCATION_PRINT(File, Loc)
f91b1629
JD
1338%}
1339
3ebecc24
JD
1340%printer { fprintf (yyoutput, "%d", @$); } <>
1341%destructor { fprintf (stderr, "DESTROY %d\n", @$); } <>
12e35840
JD
1342%printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
1343%destructor { fprintf (yyoutput, "<*> destructor should not be called"); } <*>
f91b1629
JD
1344
1345%%
1346
1347start:
1348 { @$ = 1; } // Not set or used.
1349 { USE ($$); @$ = 2; } // Both set and used.
1350 { USE ($$); @$ = 3; } // Only set.
1351 { @$ = 4; } // Only used.
1352 'c'
1353 { USE (($$, $2, $4, $5)); @$ = 0; }
1354 ;
1355
1356%%
55f48c48 1357]AT_YYERROR_DEFINE[
95361618 1358]AT_YYLEX_DEFINE[
f42c012f 1359]AT_MAIN_DEFINE[
f91b1629 1360]])
55f48c48 1361AT_BISON_OPTION_POPDEFS
f91b1629 1362
da730230 1363AT_BISON_CHECK([-o input.c input.y], 0,,
9534d2be
AD
1364[[input.y:24.70-72: warning: useless %destructor for type <*> [-Wother]
1365input.y:24.70-72: warning: useless %printer for type <*> [-Wother]
1366input.y:33.3-23: warning: unset value: $$ [-Wother]
0906b12c 1367input.y:32.3-23: warning: unused value: $3 [-Wother]
f91b1629
JD
1368]])
1369
505ece51 1370AT_BISON_CHECK([-fcaret -o input.c input.y], 0,,
f3ead217
TR
1371[[input.y:24.70-72: warning: useless %destructor for type <*> [-Wother]
1372 %printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
1373 ^^^
1374input.y:24.70-72: warning: useless %printer for type <*> [-Wother]
1375 %printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
1376 ^^^
1377input.y:33.3-23: warning: unset value: $$ [-Wother]
505ece51
TR
1378 { @$ = 4; } // Only used.
1379 ^^^^^^^^^^^^^^^^^^^^^
0906b12c 1380input.y:32.3-23: warning: unused value: $3 [-Wother]
23589235
AD
1381 { USE ($$); @$ = 3; } // Only set.
1382 ^^^^^^^^^^^^^^^^^^^^^
505ece51
TR
1383]])
1384
f91b1629 1385AT_COMPILE([input])
f42c012f 1386AT_PARSER_CHECK([./input --debug], 1,,
f91b1629
JD
1387[[Starting parse
1388Entering state 0
12e35840 1389Reducing stack by rule 1 (line 30):
f91b1629
JD
1390-> $$ = nterm $@1 (: )
1391Stack now 0
1392Entering state 2
12e35840 1393Reducing stack by rule 2 (line 31):
f91b1629
JD
1394-> $$ = nterm @2 (: 2)
1395Stack now 0 2
1396Entering state 4
12e35840 1397Reducing stack by rule 3 (line 32):
f91b1629
JD
1398-> $$ = nterm @3 (: 3)
1399Stack now 0 2 4
1400Entering state 5
12e35840 1401Reducing stack by rule 4 (line 33):
f91b1629
JD
1402-> $$ = nterm @4 (: 4)
1403Stack now 0 2 4 5
1404Entering state 6
1405Reading a token: Now at end of input.
1406syntax error
1407Error: popping nterm @4 (: 4)
1408DESTROY 4
1409Stack now 0 2 4 5
1410Error: popping nterm @3 (: 3)
1411DESTROY 3
1412Stack now 0 2 4
1413Error: popping nterm @2 (: 2)
1414DESTROY 2
1415Stack now 0 2
1416Error: popping nterm $@1 (: )
1417Stack now 0
1418Cleanup: discarding lookahead token $end (: )
1419Stack now 0
1420]])
1421
1422AT_CLEANUP
e785ccf7
JD
1423
1424
1425## ----------------------- ##
1426## @$ implies %locations. ##
1427## ----------------------- ##
1428
1429# Bison once forgot to check for @$ in actions other than semantic actions.
1430
1431# AT_CHECK_ACTION_LOCATIONS(ACTION-DIRECTIVE)
55f48c48 1432# -------------------------------------------
e785ccf7
JD
1433m4_define([AT_CHECK_ACTION_LOCATIONS],
1434[AT_SETUP([[@$ in ]$1[ implies %locations]])
f42c012f 1435AT_BISON_OPTION_PUSHDEFS([%debug])
e785ccf7
JD
1436AT_DATA_GRAMMAR([[input.y]],
1437[[%code {
1438 #include <stdio.h>
55f48c48
AD
1439]AT_YYERROR_DECLARE[
1440]AT_YYLEX_DECLARE[
e785ccf7
JD
1441}
1442
1443%debug
1444
1445]$1[ {
8d6c1b5e 1446 fprintf (stderr, "%d\n", @$.first_line);
e785ccf7
JD
1447} ]m4_if($1, [%initial-action], [], [[start]])[
1448
1449%%
1450
1451start: ;
1452
1453%%
1454
1455static int
1456yylex (void)
1457{
1458 return 0;
1459}
1460
55f48c48 1461]AT_YYERROR_DEFINE[
3ef9fa8f 1462]AT_MAIN_DEFINE[
e785ccf7
JD
1463]])
1464
da730230 1465AT_BISON_CHECK([[-o input.c input.y]])
e785ccf7 1466AT_COMPILE([[input]])
55f48c48 1467AT_BISON_OPTION_POPDEFS
e785ccf7
JD
1468AT_CLEANUP])
1469
1470AT_CHECK_ACTION_LOCATIONS([[%initial-action]])
1471AT_CHECK_ACTION_LOCATIONS([[%destructor]])
1472AT_CHECK_ACTION_LOCATIONS([[%printer]])
e8cd1ad6
DJ
1473
1474
4982f078
AD
1475## ------------------------- ##
1476## Qualified $$ in actions. ##
1477## ------------------------- ##
1478
3edfae04
AD
1479# Check that we can use qualified $$ (v.g., $<type>$) not only in rule
1480# actions, but also where $$ is valid: %destructor/%printer and
1481# %initial-action.
4982f078 1482#
3edfae04 1483# FIXME: Not actually checking %destructor, but it's the same code as
4982f078
AD
1484# %printer...
1485#
1486# To do that, use a semantic value that has two fields (sem_type),
1487# declare symbols to have only one of these types (INT, float), and
1488# use $<type>$ to get the other one. Including for symbols that are
1489# not typed (UNTYPED).
1490
1491m4_pushdef([AT_TEST],
1492[AT_SETUP([[Qualified $$ in actions: $1]])
1493
f42c012f 1494AT_BISON_OPTION_PUSHDEFS([%skeleton "$1" %debug])
4982f078
AD
1495
1496AT_DATA_GRAMMAR([[input.y]],
1497[[%skeleton "$1"
4982f078
AD
1498%debug
1499%code requires
1500{
4982f078
AD
1501 typedef struct sem_type
1502 {
1503 int ival;
1504 float fval;
1505 } sem_type;
1506
1507# define YYSTYPE sem_type
1508
4acc22e5 1509]AT_SKEL_CC_IF([[
4982f078
AD
1510# include <iostream>
1511 static void
1512 report (std::ostream& yyo, int ival, float fval)
1513 {
1514 yyo << "ival: " << ival << ", fval: " << fval;
1515 }
4acc22e5
AD
1516]], [[
1517# include <stdio.h>
4982f078
AD
1518 static void
1519 report (FILE* yyo, int ival, float fval)
1520 {
1521 fprintf (yyo, "ival: %d, fval: %1.1f", ival, fval);
1522 }
4acc22e5 1523]])[
4982f078
AD
1524}
1525
1526%code
1527{
1528 ]AT_YYERROR_DECLARE[
1529 ]AT_YYLEX_DECLARE[
1530}
1531
1532%token UNTYPED
1533%token <ival> INT
1534%type <fval> float
1535%printer { report (yyo, $$, $<fval>$); } <ival>;
1536%printer { report (yyo, $<ival>$, $$ ); } <fval>;
1537%printer { report (yyo, $<ival>$, $<fval>$); } <>;
1538
cd735a8c
AD
1539%initial-action
1540{
1541 $<ival>$ = 42;
1542 $<fval>$ = 4.2;
1543}
4982f078
AD
1544
1545%%
1546float: UNTYPED INT
1547{
1548 $$ = $<fval>1 + $<fval>2;
1549 $<ival>$ = $<ival>1 + $][2;
1550};
1551%%
1552]AT_YYERROR_DEFINE[
1553]AT_YYLEX_DEFINE(AT_SKEL_CC_IF([[{yy::parser::token::UNTYPED,
1554 yy::parser::token::INT,
1555 EOF}]],
1556 [[{UNTYPED, INT, EOF}]]),
1557 [AT_VAL.ival = toknum * 10; AT_VAL.fval = toknum / 10.0;])[
f42c012f 1558]AT_MAIN_DEFINE[
4982f078
AD
1559]])
1560
1561AT_FULL_COMPILE([[input]])
f42c012f 1562AT_PARSER_CHECK([./input --debug], 0, [], [stderr])
4982f078
AD
1563# Don't be too picky on the traces, GLR is not exactly the same. Keep
1564# only the lines from the printer.
34904c57 1565AT_CHECK([[sed -ne '/ival:/p' stderr]], 0,
4982f078
AD
1566[[Reading a token: Next token is token UNTYPED (ival: 10, fval: 0.1)
1567Shifting token UNTYPED (ival: 10, fval: 0.1)
1568Reading a token: Next token is token INT (ival: 20, fval: 0.2)
1569Shifting token INT (ival: 20, fval: 0.2)
1570 $][1 = token UNTYPED (ival: 10, fval: 0.1)
1571 $][2 = token INT (ival: 20, fval: 0.2)
1572-> $$ = nterm float (ival: 30, fval: 0.3)
1573Cleanup: popping nterm float (ival: 30, fval: 0.3)
1574]])
1575
1576AT_BISON_OPTION_POPDEFS
1577
1578AT_CLEANUP
1579])
1580
1581AT_TEST([yacc.c])
1582AT_TEST([glr.c])
1583AT_TEST([lalr1.cc])
1584AT_TEST([glr.cc])
1585
1586m4_popdef([AT_TEST])
1587
e8cd1ad6
DJ
1588## ----------------------------------------------- ##
1589## Fix user actions without a trailing semicolon. ##
1590## ----------------------------------------------- ##
1591
1592AT_SETUP([[Fix user actions without a trailing semicolon]])
1593
1594# This feature is undocumented, but we accidentally broke it in 2.3a,
1595# and there was a complaint at:
1596# <http://lists.gnu.org/archive/html/bug-bison/2008-11/msg00001.html>.
55f48c48 1597AT_BISON_OPTION_PUSHDEFS
e8cd1ad6
DJ
1598AT_DATA([input.y],
1599[[%%
1600start: test2 test1 test0 testc;
1601
1602test2
e9690142
JD
1603: 'a' { semi; /* TEST:N:2 */ }
1604| 'b' { if (0) {no_semi} /* TEST:N:2 */ }
1605| 'c' { if (0) {semi;} /* TEST:N:2 */ }
1606| 'd' { semi; no_semi /* TEST:Y:2 */ }
1607| 'e' { semi(); no_semi() /* TEST:Y:2 */ }
1608| 'f' { semi[]; no_semi[] /* TEST:Y:2 */ }
1609| 'g' { semi++; no_semi++ /* TEST:Y:2 */ }
1610| 'h' { {no_semi} no_semi /* TEST:Y:2 */ }
1611| 'i' { {semi;} no_semi /* TEST:Y:2 */ }
e8cd1ad6
DJ
1612;
1613test1
e9690142
JD
1614 : 'a' { semi; // TEST:N:1 ;
1615} | 'b' { if (0) {no_semi} // TEST:N:1 ;
1616} | 'c' { if (0) {semi;} // TEST:N:1 ;
1617} | 'd' { semi; no_semi // TEST:Y:1 ;
1618} | 'e' { semi(); no_semi() // TEST:Y:1 ;
1619} | 'f' { semi[]; no_semi[] // TEST:Y:1 ;
1620} | 'g' { semi++; no_semi++ // TEST:Y:1 ;
1621} | 'h' { {no_semi} no_semi // TEST:Y:1 ;
1622} | 'i' { {semi;} no_semi // TEST:Y:1 ;
e8cd1ad6
DJ
1623} ;
1624test0
e9690142
JD
1625 : 'a' { semi; // TEST:N:1 {}
1626} | 'b' { if (0) {no_semi} // TEST:N:1 {}
1627} | 'c' { if (0) {semi;} // TEST:N:1 {}
1628} | 'd' { semi; no_semi // TEST:Y:1 {}
1629} | 'e' { semi(); no_semi() // TEST:Y:1 {}
1630} | 'f' { semi[]; no_semi[] // TEST:Y:1 {}
1631} | 'g' { semi++; no_semi++ // TEST:Y:1 {}
1632} | 'h' { {no_semi} no_semi // TEST:Y:1 {}
1633} | 'i' { {semi;} no_semi // TEST:Y:1 {}
e8cd1ad6
DJ
1634} ;
1635
1636testc
1637: 'a' {
1638#define TEST_MACRO_N \
1639[]"broken\" $ @ $$ @$ [];\
1640string;"}
1641| 'b' {
1642no_semi
1643#define TEST_MACRO_N \
1644[]"broken\" $ @ $$ @$ [];\
1645string;"}
1646]])
55f48c48 1647AT_BISON_OPTION_POPDEFS
e8cd1ad6
DJ
1648
1649AT_BISON_CHECK([[-o input.c input.y]], [0], [],
518e8830 1650[[input.y:8.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1651input.y:8.48: future versions of Bison will not add the ';'
518e8830 1652input.y:9.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1653input.y:9.48: future versions of Bison will not add the ';'
518e8830 1654input.y:10.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1655input.y:10.48: future versions of Bison will not add the ';'
518e8830 1656input.y:11.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1657input.y:11.48: future versions of Bison will not add the ';'
518e8830 1658input.y:12.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1659input.y:12.48: future versions of Bison will not add the ';'
518e8830 1660input.y:13.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1661input.y:13.48: future versions of Bison will not add the ';'
518e8830 1662input.y:20.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1663input.y:20.1: future versions of Bison will not add the ';'
518e8830 1664input.y:21.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1665input.y:21.1: future versions of Bison will not add the ';'
518e8830 1666input.y:22.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1667input.y:22.1: future versions of Bison will not add the ';'
518e8830 1668input.y:23.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1669input.y:23.1: future versions of Bison will not add the ';'
518e8830 1670input.y:24.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1671input.y:24.1: future versions of Bison will not add the ';'
518e8830 1672input.y:25.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1673input.y:25.1: future versions of Bison will not add the ';'
518e8830 1674input.y:31.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1675input.y:31.1: future versions of Bison will not add the ';'
518e8830 1676input.y:32.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1677input.y:32.1: future versions of Bison will not add the ';'
518e8830 1678input.y:33.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1679input.y:33.1: future versions of Bison will not add the ';'
518e8830 1680input.y:34.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1681input.y:34.1: future versions of Bison will not add the ';'
518e8830 1682input.y:35.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1683input.y:35.1: future versions of Bison will not add the ';'
518e8830 1684input.y:36.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
d4e985d5 1685input.y:36.1: future versions of Bison will not add the ';'
e8cd1ad6 1686]])
6617622c
AD
1687
1688AT_MATCHES_CHECK([input.c], [[/\* TEST:N:2 \*/ \}$]], [[3]])
1689AT_MATCHES_CHECK([input.c], [[/\* TEST:Y:2 \*/ ;\}$]], [[6]])
1690AT_MATCHES_CHECK([input.c], [[// TEST:N:1 [;{}]*\n\}$]], [[6]])
1691AT_MATCHES_CHECK([input.c], [[// TEST:Y:1 [;{}]*\n;\}$]], [[12]])
1692AT_MATCHES_CHECK([input.c], [[#define TEST_MACRO_N \\\n\[\]"broken\\" \$ \@ \$\$ \@\$ \[\];\\\nstring;"\}]], [[2]])
e8cd1ad6
DJ
1693
1694AT_CLEANUP
df222dfa
JD
1695
1696
1697## -------------------------------------------------- ##
1698## Destroying lookahead assigned by semantic action. ##
1699## -------------------------------------------------- ##
1700
1701AT_SETUP([[Destroying lookahead assigned by semantic action]])
1702
55f48c48 1703AT_BISON_OPTION_PUSHDEFS
df222dfa
JD
1704AT_DATA_GRAMMAR([input.y],
1705[[
1706%code {
1707 #include <assert.h>
1708 #include <stdio.h>
55f48c48
AD
1709]AT_YYERROR_DECLARE[
1710]AT_YYLEX_DECLARE[
df222dfa
JD
1711 #define USE(Var)
1712}
1713
1714%destructor { fprintf (stderr, "'a' destructor\n"); } 'a'
1715%destructor { fprintf (stderr, "'b' destructor\n"); } 'b'
1716
1717%%
1718
1719// In a previous version of Bison, yychar assigned by the semantic
1720// action below was not translated into yytoken before the lookahead was
1721// discarded and thus before its destructor (selected according to
1722// yytoken) was called in order to return from yyparse. This would
1723// happen even if YYACCEPT was performed in a later semantic action as
1724// long as only consistent states with default reductions were visited
1725// in between. However, we leave YYACCEPT in the same semantic action
1726// for this test in order to show that skeletons cannot simply translate
1727// immediately after every semantic action because a semantic action
1728// that has set yychar might not always return normally. Instead,
1729// skeletons must translate before every use of yytoken.
1730start: 'a' accept { USE($1); } ;
684083f0 1731accept: %empty {
df222dfa
JD
1732 assert (yychar == YYEMPTY);
1733 yychar = 'b';
1734 YYACCEPT;
1735} ;
1736
1737%%
55f48c48 1738]AT_YYERROR_DEFINE[
95361618 1739]AT_YYLEX_DEFINE(["a"])[
3ef9fa8f 1740]AT_MAIN_DEFINE[
df222dfa 1741]])
55f48c48 1742AT_BISON_OPTION_POPDEFS
df222dfa
JD
1743AT_BISON_CHECK([[-o input.c input.y]])
1744AT_COMPILE([[input]])
1745AT_PARSER_CHECK([[./input]], [[0]], [],
1746[['b' destructor
1747'a' destructor
1748]])
1749
1750AT_CLEANUP
d115aad9
AD
1751
1752## ---------- ##
1753## YYBACKUP. ##
1754## ---------- ##
1755
1756AT_SETUP([[YYBACKUP]])
1757
f42c012f 1758AT_BISON_OPTION_PUSHDEFS([%pure-parser %debug])
55f48c48 1759
d115aad9
AD
1760AT_DATA_GRAMMAR([input.y],
1761[[
1762%error-verbose
1763%debug
1764%pure-parser
1765%code {
1766# include <stdio.h>
1767# include <stdlib.h>
1768# include <assert.h>
1769
55f48c48 1770 ]AT_YYERROR_DECLARE[
087dcd78 1771 ]AT_YYLEX_DECLARE[
d115aad9
AD
1772}
1773%%
1774input:
1775 exp exp {}
1776;
1777
1778exp:
1779 'a' { printf ("a: %d\n", $1); }
1780| 'b' { YYBACKUP('a', 123); }
1781| 'c' 'd' { YYBACKUP('a', 456); }
1782;
1783
1784%%
55f48c48 1785]AT_YYERROR_DEFINE[
087dcd78 1786]AT_YYLEX_DEFINE(["bcd"], [*lvalp = (toknum + 1) * 10])[
3ef9fa8f 1787]AT_MAIN_DEFINE[
d115aad9 1788]])
55f48c48 1789AT_BISON_OPTION_POPDEFS
d115aad9
AD
1790
1791AT_BISON_CHECK([[-o input.c input.y]])
1792AT_COMPILE([[input]])
1793AT_PARSER_CHECK([[./input]], [[0]],
1794[[a: 123
1795a: 456
d115aad9
AD
1796]])
1797
1798AT_CLEANUP