Home | History | Annotate | Download | only in tests
      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