Home | History | Annotate | Download | only in tests
      1 # Simple calculator.                         -*- Autotest -*-
      2 
      3 # Copyright (C) 2000-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 ## ---------------------------------------------------- ##
     19 ## Compile the grammar described in the documentation.  ##
     20 ## ---------------------------------------------------- ##
     21 
     22 
     23 # ------------------------- #
     24 # Helping Autotest macros.  #
     25 # ------------------------- #
     26 
     27 
     28 # _AT_DATA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES])
     29 # -----------------------------------------------
     30 # Produce `calc.y' and, if %defines was specified, `calc-lex.c' or
     31 # `calc-lex.cc'.
     32 #
     33 # Don't call this macro directly, because it contains some occurrences
     34 # of `$1' etc. which will be interpreted by m4.  So you should call it
     35 # with $1, $2, and $3 as arguments, which is what AT_DATA_CALC_Y does.
     36 #
     37 # When %defines is not passed, generate a single self-contained file.
     38 # Otherwise, generate three: calc.y with the parser, calc-lex.c with
     39 # the scanner, and calc-main.c with "main()".  This is in order to
     40 # stress the use of the generated parser header.  To avoid code
     41 # duplication, AT_CALC_LEX and AT_CALC_MAIN contain the body of these
     42 # two later files.
     43 m4_define([_AT_DATA_CALC_Y],
     44 [m4_if([$1$2$3], $[1]$[2]$[3], [],
     45        [m4_fatal([$0: Invalid arguments: $@])])dnl
     46 
     47 m4_pushdef([AT_CALC_MAIN],
     48 [#include <assert.h>
     49 #if HAVE_UNISTD_H
     50 # include <unistd.h>
     51 #else
     52 # undef alarm
     53 # define alarm(seconds) /* empty */
     54 #endif
     55 
     56 AT_SKEL_CC_IF([[
     57 /* A C++ ]AT_NAME_PREFIX[parse that simulates the C signature.  */
     58 int
     59 ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([semantic_value *result, int *count]))[
     60 {
     61   ]AT_NAME_PREFIX[::parser parser]AT_PARAM_IF([ (result, count)])[;
     62 #if ]AT_API_PREFIX[DEBUG
     63   parser.set_debug_level (1);
     64 #endif
     65   return parser.parse ();
     66 }
     67 ]])[
     68 
     69 semantic_value global_result = 0;
     70 int global_count = 0;
     71 
     72 /* A C main function.  */
     73 int
     74 main (int argc, const char **argv)
     75 {
     76   semantic_value result = 0;
     77   int count = 0;
     78   int status;
     79 
     80   /* This used to be alarm (10), but that isn't enough time for
     81      a July 1995 vintage DEC Alphastation 200 4/100 system,
     82      according to Nelson H. F. Beebe.  100 seconds is enough.  */
     83   alarm (100);
     84 
     85   if (argc == 2)
     86     input = fopen (argv[1], "r");
     87   else
     88     input = stdin;
     89 
     90   if (!input)
     91     {
     92       perror (argv[1]);
     93       return 3;
     94     }
     95 
     96 ]AT_SKEL_CC_IF([], [m4_bmatch([$4], [%debug],
     97 [  ]AT_NAME_PREFIX[debug = 1;])])[
     98   status = ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([[&result, &count]])[);
     99   if (fclose (input))
    100     perror ("fclose");
    101   assert (global_result == result);
    102   assert (global_count == count);
    103   return status;
    104 }
    105 ]])
    106 
    107 
    108 m4_pushdef([AT_CALC_LEX],
    109 [[#include <ctype.h>
    110 
    111 ]AT_YYLEX_DECLARE_EXTERN[
    112 static int get_char (]AT_YYLEX_FORMALS[);
    113 static void unget_char (]AT_YYLEX_PRE_FORMALS[ int c);
    114 
    115 ]AT_LOCATION_IF([
    116 static AT_YYLTYPE last_yylloc;
    117 ])[
    118 static int
    119 get_char (]AT_YYLEX_FORMALS[)
    120 {
    121   int res = getc (input);
    122   ]AT_USE_LEX_ARGS[;
    123 ]AT_LOCATION_IF([
    124   last_yylloc = AT_LOC;
    125   if (res == '\n')
    126     {
    127       AT_LOC_LAST_LINE++;
    128       AT_LOC_LAST_COLUMN = 1;
    129     }
    130   else
    131     AT_LOC_LAST_COLUMN++;
    132 ])[
    133   return res;
    134 }
    135 
    136 static void
    137 unget_char (]AT_YYLEX_PRE_FORMALS[ int c)
    138 {
    139   ]AT_USE_LEX_ARGS[;
    140 ]AT_LOCATION_IF([
    141   /* Wrong when C == `\n'. */
    142   AT_LOC = last_yylloc;
    143 ])[
    144   ungetc (c, input);
    145 }
    146 
    147 static int
    148 read_signed_integer (]AT_YYLEX_FORMALS[)
    149 {
    150   int c = get_char (]AT_YYLEX_ARGS[);
    151   int sign = 1;
    152   int n = 0;
    153 
    154   ]AT_USE_LEX_ARGS[;
    155   if (c == '-')
    156     {
    157       c = get_char (]AT_YYLEX_ARGS[);
    158       sign = -1;
    159     }
    160 
    161   while (isdigit (c))
    162     {
    163       n = 10 * n + (c - '0');
    164       c = get_char (]AT_YYLEX_ARGS[);
    165     }
    166 
    167   unget_char (]AT_YYLEX_PRE_ARGS[ c);
    168 
    169   return sign * n;
    170 }
    171 
    172 
    173 /*---------------------------------------------------------------.
    174 | Lexical analyzer returns an integer on the stack and the token |
    175 | NUM, or the ASCII character read if not a number.  Skips all   |
    176 | blanks and tabs, returns 0 for EOF.                            |
    177 `---------------------------------------------------------------*/
    178 
    179 ]AT_YYLEX_PROTOTYPE[
    180 {
    181   int c;
    182   /* Skip current token, then white spaces.  */
    183   do
    184     {
    185 ]AT_LOCATION_IF(
    186 [     AT_LOC_FIRST_COLUMN = AT_LOC_LAST_COLUMN;
    187       AT_LOC_FIRST_LINE   = AT_LOC_LAST_LINE;
    188 ])[
    189     }
    190   while ((c = get_char (]AT_YYLEX_ARGS[)) == ' ' || c == '\t');
    191 
    192   /* process numbers   */
    193   if (c == '.' || isdigit (c))
    194     {
    195       unget_char (]AT_YYLEX_PRE_ARGS[ c);
    196       ]AT_VAL[.ival = read_signed_integer (]AT_YYLEX_ARGS[);
    197       return NUM;
    198     }
    199 
    200   /* Return end-of-file.  */
    201   if (c == EOF)
    202     return CALC_EOF;
    203 
    204   /* Return single chars. */
    205   return c;
    206 }
    207 ]])
    208 
    209 AT_DATA_GRAMMAR([calc.y],
    210 [[/* Infix notation calculator--calc */
    211 ]$4
    212 AT_SKEL_CC_IF(
    213 [%define global_tokens_and_yystype])[
    214 %code requires
    215 {
    216 ]AT_LOCATION_TYPE_IF([[
    217 # include <iostream>
    218   struct Point
    219   {
    220     int l;
    221     int c;
    222   };
    223 
    224   struct Span
    225   {
    226     Point first;
    227     Point last;
    228   };
    229 
    230 # define YYLLOC_DEFAULT(Current, Rhs, N)                                \
    231   do                                                                    \
    232     if (N)                                                              \
    233       {                                                                 \
    234         (Current).first = YYRHSLOC (Rhs, 1).first;                      \
    235         (Current).last  = YYRHSLOC (Rhs, N).last;                       \
    236       }                                                                 \
    237     else                                                                \
    238       {                                                                 \
    239         (Current).first = (Current).last = YYRHSLOC (Rhs, 0).last;      \
    240       }                                                                 \
    241   while (false)
    242 
    243 ]])[
    244   /* Exercise pre-prologue dependency to %union.  */
    245   typedef int semantic_value;
    246 }
    247 
    248 /* Exercise %union. */
    249 %union
    250 {
    251   semantic_value ival;
    252 };
    253 %printer { ]AT_SKEL_CC_IF([[yyoutput << $$]],
    254                           [[fprintf (yyoutput, "%d", $$)]])[; } <ival>;
    255 
    256 %code provides
    257 {
    258   #include <stdio.h>
    259   /* The input.  */
    260   extern FILE *input;
    261   extern semantic_value global_result;
    262   extern int global_count;
    263 }
    264 
    265 %code
    266 {
    267 #include <assert.h>
    268 #include <string.h>
    269 #define USE(Var)
    270 
    271 FILE *input;
    272 static int power (int base, int exponent);
    273 
    274 ]AT_YYERROR_DECLARE[
    275 ]AT_YYLEX_DECLARE_EXTERN[
    276 }
    277 
    278 ]AT_SKEL_CC_IF([AT_LOCATION_TYPE_IF([[
    279 %initial-action
    280 {
    281   @$.first.l = @$.first.c = 1;
    282   @$.last = @$.first;
    283 }]])])[
    284 
    285 /* Bison Declarations */
    286 %token CALC_EOF 0 "end of input"
    287 %token <ival> NUM "number"
    288 %type  <ival> exp
    289 
    290 %nonassoc '=' /* comparison            */
    291 %left '-' '+'
    292 %left '*' '/'
    293 %left NEG     /* negation--unary minus */
    294 %right '^'    /* exponentiation        */
    295 
    296 /* Grammar follows */
    297 %%
    298 input:
    299   line
    300 | input line         { ]AT_PARAM_IF([++*count; ++global_count;])[ }
    301 ;
    302 
    303 line:
    304   '\n'
    305 | exp '\n'           { ]AT_PARAM_IF([*result = global_result = $1], [USE ($1)])[; }
    306 ;
    307 
    308 exp:
    309   NUM                { $$ = $1;             }
    310 | exp '=' exp
    311   {
    312     if ($1 != $3)
    313       fprintf (stderr, "calc: error: %d != %d\n", $1, $3);
    314     $$ = $1;
    315   }
    316 | exp '+' exp        { $$ = $1 + $3;        }
    317 | exp '-' exp        { $$ = $1 - $3;        }
    318 | exp '*' exp        { $$ = $1 * $3;        }
    319 | exp '/' exp        { $$ = $1 / $3;        }
    320 | '-' exp  %prec NEG { $$ = -$2;            }
    321 | exp '^' exp        { $$ = power ($1, $3); }
    322 | '(' exp ')'        { $$ = $2;             }
    323 | '(' error ')'      { $$ = 1111; yyerrok;  }
    324 | '!'                { $$ = 0; YYERROR;     }
    325 | '-' error          { $$ = 0; YYERROR;     }
    326 ;
    327 %%
    328 
    329 static int
    330 power (int base, int exponent)
    331 {
    332   int res = 1;
    333   assert (0 <= exponent);
    334   for (/* Niente */; exponent; --exponent)
    335     res *= base;
    336   return res;
    337 }
    338 
    339 ]AT_SKEL_CC_IF(
    340 [AT_LOCATION_TYPE_IF([[
    341   std::ostream&
    342   operator<< (std::ostream& o, const Span& s)
    343   {
    344     o << s.first.l << '.' << s.first.c;
    345     if (s.first.l != s.last.l)
    346       o << '-' << s.last.l << '.' << s.last.c - 1;
    347     else if (s.first.c != s.last.c - 1)
    348       o << '-' << s.last.c - 1;
    349     return o;
    350   }
    351 ]])])[
    352 ]AT_YYERROR_DEFINE[
    353 ]AT_DEFINES_IF([],
    354 [AT_CALC_LEX
    355 AT_CALC_MAIN])])
    356 
    357 AT_DEFINES_IF([AT_DATA_SOURCE([[calc-lex.c]AT_SKEL_CC_IF([[c]])],
    358 [[#include "calc.h]AT_SKEL_CC_IF([[h]])["
    359 
    360 ]AT_CALC_LEX])
    361 AT_DATA_SOURCE([[calc-main.c]AT_SKEL_CC_IF([[c]])],
    362 [[#include "calc.h]AT_SKEL_CC_IF([[h]])["
    363 
    364 ]AT_CALC_MAIN])
    365 ])
    366 m4_popdef([AT_CALC_MAIN])
    367 m4_popdef([AT_CALC_LEX])
    368 ])# _AT_DATA_CALC_Y
    369 
    370 
    371 # AT_DATA_CALC_Y([BISON-OPTIONS])
    372 # -------------------------------
    373 # Produce `calc.y' and, if %defines was specified, `calc-lex.c' or
    374 # `calc-lex.cc'.
    375 m4_define([AT_DATA_CALC_Y],
    376 [_AT_DATA_CALC_Y($[1], $[2], $[3], [$1])
    377 ])
    378 
    379 
    380 
    381 # _AT_CHECK_CALC(BISON-OPTIONS, INPUT, [NUM-STDERR-LINES])
    382 # --------------------------------------------------------
    383 # Run `calc' on INPUT and expect no STDOUT nor STDERR.
    384 #
    385 # If BISON-OPTIONS contains `%debug' but not `%glr-parser', then
    386 #
    387 # NUM-STDERR-LINES is the number of expected lines on stderr.
    388 # Currently this is ignored, though, since the output format is fluctuating.
    389 #
    390 # We don't count GLR's traces yet, since its traces are somewhat
    391 # different from LALR's.
    392 m4_define([_AT_CHECK_CALC],
    393 [AT_DATA([[input]],
    394 [[$2
    395 ]])
    396 AT_PARSER_CHECK([./calc input], 0, [], [stderr])
    397 ])
    398 
    399 
    400 # _AT_CHECK_CALC_ERROR(BISON-OPTIONS, EXIT-STATUS, INPUT,
    401 #                      [NUM-STDERR-LINES],
    402 #                      [VERBOSE-AND-LOCATED-ERROR-MESSAGE])
    403 # ---------------------------------------------------------
    404 # Run `calc' on INPUT, and expect a `syntax error' message.
    405 #
    406 # If INPUT starts with a slash, it is used as absolute input file name,
    407 # otherwise as contents.
    408 #
    409 # NUM-STDERR-LINES is the number of expected lines on stderr.
    410 # Currently this is ignored, though, since the output format is fluctuating.
    411 #
    412 # If BISON-OPTIONS contains `%location', then make sure the ERROR-LOCATION
    413 # is correctly output on stderr.
    414 #
    415 # If BISON-OPTIONS contains `%error-verbose', then make sure the
    416 # IF-YYERROR-VERBOSE message is properly output after `syntax error, '
    417 # on STDERR.
    418 #
    419 # If BISON-OPTIONS contains `%debug' but not `%glr', then NUM-STDERR-LINES
    420 # is the number of expected lines on stderr.
    421 m4_define([_AT_CHECK_CALC_ERROR],
    422 [m4_bmatch([$3], [^/],
    423            [AT_PARSER_CHECK([./calc $3], $2, [], [stderr])],
    424            [AT_DATA([[input]],
    425 [[$3
    426 ]])
    427 AT_PARSER_CHECK([./calc input], $2, [], [stderr])])
    428 
    429 # Normalize the observed and expected error messages, depending upon the
    430 # options.
    431 # 1. Remove the traces from observed.
    432 sed '/^Starting/d
    433 /^Entering/d
    434 /^Stack/d
    435 /^Reading/d
    436 /^Reducing/d
    437 /^Return/d
    438 /^Shifting/d
    439 /^state/d
    440 /^Cleanup:/d
    441 /^Error:/d
    442 /^Next/d
    443 /^Now/d
    444 /^Discarding/d
    445 / \$[[0-9$]]* = /d
    446 /^yydestructor:/d' stderr >at-stderr
    447 mv at-stderr stderr
    448 # 2. Create the reference error message.
    449 AT_DATA([[expout]],
    450 [$5
    451 ])
    452 # 3. If locations are not used, remove them.
    453 AT_YYERROR_SEES_LOC_IF([],
    454 [[sed 's/^[-0-9.]*: //' expout >at-expout
    455 mv at-expout expout]])
    456 # 4. If error-verbose is not used, strip the`, unexpected....' part.
    457 m4_bmatch([$1], [%error-verbose], [],
    458 [[sed 's/syntax error, .*$/syntax error/' expout >at-expout
    459 mv at-expout expout]])
    460 # 5. Check
    461 AT_CHECK([cat stderr], 0, [expout])
    462 ])
    463 
    464 
    465 # AT_CHECK_SPACES([FILE])
    466 # -----------------------
    467 # Make sure we did not introduce bad spaces.  Checked here because all
    468 # the skeletons are (or should be) exercized here.
    469 m4_define([AT_CHECK_SPACES],
    470 [AT_CHECK([$PERL -ne '
    471   chomp;
    472   print "$.: {$_}\n"
    473     if (# No starting/ending empty lines.
    474         (eof || $. == 1) && /^\s*$/
    475         # No trailing space.  FIXME: not ready for "maint".
    476         # || /\s$/
    477         )' $1
    478 ])dnl
    479 ])
    480 
    481 
    482 # AT_CHECK_CALC([BISON-OPTIONS])
    483 # ------------------------------
    484 # Start a testing chunk which compiles `calc' grammar with
    485 # BISON-OPTIONS, and performs several tests over the parser.
    486 m4_define([AT_CHECK_CALC],
    487 [m4_ifval([$2], [m4_fatal([$0: expected a single argument])])
    488 
    489 # We use integers to avoid dependencies upon the precision of doubles.
    490 AT_SETUP([Calculator $1])
    491 
    492 AT_BISON_OPTION_PUSHDEFS([$1])
    493 
    494 AT_DATA_CALC_Y([$1])
    495 AT_FULL_COMPILE([calc], AT_DEFINES_IF([[lex], [main]]))
    496 AT_CHECK_SPACES([calc.AT_SKEL_CC_IF([cc], [c])])
    497 AT_DEFINES_IF([AT_CHECK_SPACES([calc.AT_SKEL_CC_IF([hh], [h])])])
    498 
    499 # Test the priorities.
    500 _AT_CHECK_CALC([$1],
    501 [1 + 2 * 3 = 7
    502 1 + 2 * -3 = -5
    503 
    504 -1^2 = -1
    505 (-1)^2 = 1
    506 
    507 ---1 = -1
    508 
    509 1 - 2 - 3 = -4
    510 1 - (2 - 3) = 2
    511 
    512 2^2^3 = 256
    513 (2^2)^3 = 64],
    514                [842])
    515 
    516 # Some syntax errors.
    517 _AT_CHECK_CALC_ERROR([$1], [1], [1 2], [15],
    518                      [1.3: syntax error, unexpected number])
    519 _AT_CHECK_CALC_ERROR([$1], [1], [1//2], [20],
    520                      [1.3: syntax error, unexpected '/', expecting number or '-' or '(' or '!'])
    521 _AT_CHECK_CALC_ERROR([$1], [1], [error], [5],
    522                      [1.1: syntax error, unexpected $undefined])
    523 _AT_CHECK_CALC_ERROR([$1], [1], [1 = 2 = 3], [30],
    524                      [1.7: syntax error, unexpected '='])
    525 _AT_CHECK_CALC_ERROR([$1], [1],
    526                      [
    527 +1],
    528                      [20],
    529                      [2.1: syntax error, unexpected '+'])
    530 # Exercise error messages with EOF: work on an empty file.
    531 _AT_CHECK_CALC_ERROR([$1], [1], [/dev/null], [4],
    532                      [1.1: syntax error, unexpected end of input])
    533 
    534 # Exercise the error token: without it, we die at the first error,
    535 # hence be sure to
    536 #
    537 # - have several errors which exercise different shift/discardings
    538 #   - (): nothing to pop, nothing to discard
    539 #   - (1 + 1 + 1 +): a lot to pop, nothing to discard
    540 #   - (* * *): nothing to pop, a lot to discard
    541 #   - (1 + 2 * *): some to pop and discard
    542 #
    543 # - test the action associated to `error'
    544 #
    545 # - check the lookahead that triggers an error is not discarded
    546 #   when we enter error recovery.  Below, the lookahead causing the
    547 #   first error is ")", which is needed to recover from the error and
    548 #   produce the "0" that triggers the "0 != 1" error.
    549 #
    550 _AT_CHECK_CALC_ERROR([$1], [0],
    551                      [() + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1],
    552                      [250],
    553 [1.2: syntax error, unexpected ')', expecting number or '-' or '(' or '!'
    554 1.18: syntax error, unexpected ')', expecting number or '-' or '(' or '!'
    555 1.23: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
    556 1.41: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
    557 calc: error: 4444 != 1])
    558 
    559 # The same, but this time exercising explicitly triggered syntax errors.
    560 # POSIX says the lookahead causing the error should not be discarded.
    561 _AT_CHECK_CALC_ERROR([$1], [0], [(!) + (1 2) = 1], [102],
    562 [1.10: syntax error, unexpected number
    563 calc: error: 2222 != 1])
    564 _AT_CHECK_CALC_ERROR([$1], [0], [(- *) + (1 2) = 1], [113],
    565 [1.4: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
    566 1.12: syntax error, unexpected number
    567 calc: error: 2222 != 1])
    568 
    569 # Check that yyerrok works properly: second error is not reported,
    570 # third and fourth are.  Parse status is succesfull.
    571 _AT_CHECK_CALC_ERROR([$1], [0], [(* *) + (*) + (*)], [113],
    572 [1.2: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
    573 1.10: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
    574 1.16: syntax error, unexpected '*', expecting number or '-' or '(' or '!'])
    575 
    576 AT_BISON_OPTION_POPDEFS
    577 
    578 AT_CLEANUP
    579 ])# AT_CHECK_CALC
    580 
    581 
    582 
    583 
    584 # ------------------------ #
    585 # Simple LALR Calculator.  #
    586 # ------------------------ #
    587 
    588 AT_BANNER([[Simple LALR(1) Calculator.]])
    589 
    590 # AT_CHECK_CALC_LALR([BISON-OPTIONS])
    591 # -----------------------------------
    592 # Start a testing chunk which compiles `calc' grammar with
    593 # BISON-OPTIONS, and performs several tests over the parser.
    594 m4_define([AT_CHECK_CALC_LALR],
    595 [AT_CHECK_CALC($@)])
    596 
    597 AT_CHECK_CALC_LALR()
    598 
    599 AT_CHECK_CALC_LALR([%defines])
    600 AT_CHECK_CALC_LALR([%locations])
    601 
    602 AT_CHECK_CALC_LALR([%name-prefix="calc"]) dnl test deprecated `='
    603 AT_CHECK_CALC_LALR([%verbose])
    604 AT_CHECK_CALC_LALR([%yacc])
    605 AT_CHECK_CALC_LALR([%error-verbose])
    606 
    607 AT_CHECK_CALC_LALR([%define api.pure full %locations])
    608 AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full %locations])
    609 AT_CHECK_CALC_LALR([%error-verbose %locations])
    610 
    611 AT_CHECK_CALC_LALR([%error-verbose %locations %defines %name-prefix "calc" %verbose %yacc])
    612 AT_CHECK_CALC_LALR([%error-verbose %locations %defines %define api.prefix "calc" %verbose %yacc])
    613 
    614 AT_CHECK_CALC_LALR([%debug])
    615 AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
    616 AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
    617 
    618 AT_CHECK_CALC_LALR([%define api.pure full %verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
    619 AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full %verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
    620 
    621 AT_CHECK_CALC_LALR([%define api.pure %error-verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
    622 
    623 
    624 # ----------------------- #
    625 # Simple GLR Calculator.  #
    626 # ----------------------- #
    627 
    628 AT_BANNER([[Simple GLR Calculator.]])
    629 
    630 # AT_CHECK_CALC_GLR([BISON-OPTIONS])
    631 # ----------------------------------
    632 # Start a testing chunk which compiles `calc' grammar with
    633 # BISON-OPTIONS and %glr-parser, and performs several tests over the parser.
    634 m4_define([AT_CHECK_CALC_GLR],
    635 [AT_CHECK_CALC([%glr-parser] $@)])
    636 
    637 
    638 AT_CHECK_CALC_GLR()
    639 
    640 AT_CHECK_CALC_GLR([%defines])
    641 AT_CHECK_CALC_GLR([%locations])
    642 AT_CHECK_CALC_GLR([%name-prefix "calc"])
    643 AT_CHECK_CALC_GLR([%define api.prefix "calc"])
    644 AT_CHECK_CALC_GLR([%verbose])
    645 AT_CHECK_CALC_GLR([%yacc])
    646 AT_CHECK_CALC_GLR([%error-verbose])
    647 
    648 AT_CHECK_CALC_GLR([%define api.pure %locations])
    649 AT_CHECK_CALC_GLR([%error-verbose %locations])
    650 
    651 AT_CHECK_CALC_GLR([%error-verbose %locations %defines %name-prefix "calc" %verbose %yacc])
    652 
    653 AT_CHECK_CALC_GLR([%debug])
    654 AT_CHECK_CALC_GLR([%error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
    655 AT_CHECK_CALC_GLR([%error-verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
    656 
    657 AT_CHECK_CALC_GLR([%define api.pure %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
    658 
    659 AT_CHECK_CALC_GLR([%define api.pure %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
    660 AT_CHECK_CALC_GLR([%define api.pure %error-verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
    661 
    662 
    663 # ----------------------------- #
    664 # Simple LALR1 C++ Calculator.  #
    665 # ----------------------------- #
    666 
    667 AT_BANNER([[Simple LALR(1) C++ Calculator.]])
    668 
    669 # First let's try using %skeleton
    670 AT_CHECK_CALC([%skeleton "lalr1.cc" %defines %locations])
    671 
    672 # AT_CHECK_CALC_LALR1_CC([BISON-OPTIONS])
    673 # ---------------------------------------
    674 # Start a testing chunk which compiles `calc' grammar with
    675 # the C++ skeleton, and performs several tests over the parser.
    676 m4_define([AT_CHECK_CALC_LALR1_CC],
    677 [AT_CHECK_CALC([%language "C++" %defines %locations] $@)])
    678 
    679 AT_CHECK_CALC_LALR1_CC([])
    680 AT_CHECK_CALC_LALR1_CC([%define api.location.type Span])
    681 AT_CHECK_CALC_LALR1_CC([%error-verbose %name-prefix "calc" %verbose %yacc])
    682 AT_CHECK_CALC_LALR1_CC([%error-verbose %define api.prefix "calc" %verbose %yacc])
    683 AT_CHECK_CALC_LALR1_CC([%error-verbose %debug %name-prefix "calc" %verbose %yacc])
    684 
    685 AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %define api.prefix "calc" %verbose %yacc])
    686 
    687 AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
    688 AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
    689 
    690 
    691 
    692 # --------------------------- #
    693 # Simple GLR C++ Calculator.  #
    694 # --------------------------- #
    695 
    696 AT_BANNER([[Simple GLR C++ Calculator.]])
    697 
    698 # Again, we try also using %skeleton.
    699 AT_CHECK_CALC([%skeleton "glr.cc" %defines %locations])
    700 
    701 # AT_CHECK_CALC_GLR_CC([BISON-OPTIONS])
    702 # -------------------------------------
    703 # Start a testing chunk which compiles `calc' grammar with
    704 # the GLR C++ skeleton, and performs several tests over the parser.
    705 m4_define([AT_CHECK_CALC_GLR_CC],
    706 [AT_CHECK_CALC([%language "C++" %glr-parser %defines %locations] $@)])
    707 
    708 AT_CHECK_CALC_GLR_CC([])
    709 AT_CHECK_CALC_GLR_CC([%define api.location.type Span])
    710 AT_CHECK_CALC_GLR_CC([%error-verbose %name-prefix "calc" %verbose %yacc])
    711 AT_CHECK_CALC_GLR_CC([%error-verbose %define api.prefix "calc" %verbose %yacc])
    712 
    713 AT_CHECK_CALC_GLR_CC([%debug])
    714 AT_CHECK_CALC_GLR_CC([%error-verbose %debug %name-prefix "calc" %verbose %yacc])
    715 
    716 AT_CHECK_CALC_GLR_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc])
    717 
    718 AT_CHECK_CALC_GLR_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
    719 AT_CHECK_CALC_GLR_CC([%pure-parser %error-verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
    720