-AT_DATA_GRAMMAR([calc.y],
-[[/* Infix notation calculator--calc */
-]$4[
-%{
-#include <stdio.h>
-
-#include <stdlib.h>
-#include <string.h>
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#else
-# undef alarm
-# define alarm(seconds) /* empty */
-#endif
-#include <ctype.h>
-
-/* Exercise pre-prologue dependency to %union. */
-typedef int semantic_value;
-
-static semantic_value global_result = 0;
-static int global_count = 0;
-%}
-
-/* Exercise %union. */
-%union
-{
- semantic_value ival;
-};
-
-%{
-static int power (int base, int exponent);
-]AT_LALR1_CC_IF([typedef yy::Location YYLTYPE;],
-[/* yyerror receives the location if:
- - %location & %pure & %glr
- - %location & %pure & %yacc & %parse-param. */
-static void yyerror (AT_YYERROR_ARG_LOC_IF([YYLTYPE *yylloc, ])
- AT_PARAM_IF([semantic_value *result, int *count, ])
- const char *s
- );])[
-static int yylex (]AT_LEX_FORMALS[);
-static int yygetc (]AT_LEX_FORMALS[);
-static void yyungetc (]AT_LEX_PRE_FORMALS[ int c);
-%}
-
-/* Bison Declarations */
-%token CALC_EOF 0 "end of input"
-%token <ival> NUM "number"
-%type <ival> exp
-
-%nonassoc '=' /* comparison */
-%left '-' '+'
-%left '*' '/'
-%left NEG /* negation--unary minus */
-%right '^' /* exponentiation */
-
-/* Grammar follows */
-%%
-input:
- line
-| input line { ]AT_PARAM_IF([++*count; ++global_count;])[ }
-;
-
-line:
- '\n'
-| exp '\n' { ]AT_PARAM_IF([*result = global_result = $1;])[ }
-;
-
-exp:
- NUM { $$ = $1; }
-| exp '=' exp
- {
- if ($1 != $3)
- fprintf (stderr, "calc: error: %d != %d\n", $1, $3);
- $$ = $1;
- }
-| exp '+' exp { $$ = $1 + $3; }
-| exp '-' exp { $$ = $1 - $3; }
-| exp '*' exp { $$ = $1 * $3; }
-| exp '/' exp { $$ = $1 / $3; }
-| '-' exp %prec NEG { $$ = -$2; }
-| exp '^' exp { $$ = power ($1, $3); }
-| '(' exp ')' { $$ = $2; }
-| '(' error ')' { $$ = 1111; }
-| '!' { YYERROR; }
-| '-' error { YYERROR; }
-;
-%%
-/* The input. */
-static FILE *yyin;
-
-]AT_LALR1_CC_IF(
-[/* Currently, print_ is required in C++. */
-void
-yy::Parser::print_ ()
-{
-AT_LOCATION_IF([
- std::cerr << location;])
-}
-
-/* A C++ error reporting function. */
-void
-yy::Parser::error_ ()
-{
- std::cerr << AT_LOCATION_IF([location << ": " << ])message << std::endl;
-}
-
-int
-yyparse (AT_PARAM_IF([semantic_value *result, int *count]))
-{
- yy::Parser parser (!!YYDEBUG[]AT_LOCATION_IF([, yy::Location ()])AT_PARAM_IF([, result, count]));
- return parser.parse ();
-}
-],
-[static void
-yyerror (AT_YYERROR_ARG_LOC_IF([YYLTYPE *yylloc, ])
- AT_PARAM_IF([semantic_value *result, int *count, ])
- const char *s)
-{
-AT_PARAM_IF([(void) result; (void) count;])
-AT_YYERROR_SEES_LOC_IF([
- fprintf (stderr, "%d.%d",
- AT_LOC.first_line, AT_LOC.first_column);
- if (AT_LOC.first_line != AT_LOC.last_line)
- fprintf (stderr, "-%d.%d",
- AT_LOC.last_line, AT_LOC.last_column - 1);
- else if (AT_LOC.first_column != AT_LOC.last_column - 1)
- fprintf (stderr, "-%d",
- AT_LOC.last_column - 1);
- fprintf (stderr, ": ");])
- fprintf (stderr, "%s\n", s);
-}])[