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