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