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