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