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