X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/520144aadc34f57ac0572ded66ab62fc32cb3069..7aaaad6c6dc0fae412d608dcf20a3977d8902cd1:/tests/calc.at diff --git a/tests/calc.at b/tests/calc.at index 477c92d3..55b91544 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -33,21 +33,90 @@ # Don't call this macro directly, because it contains some occurrences # of `$1' etc. which will be interpreted by m4. So you should call it # with $1, $2, and $3 as arguments, which is what AT_DATA_CALC_Y does. +# +# When %defines is not passed, generate a single self-contained file. +# Otherwise, generate three: calc.y with the parser, calc-lex.c with +# the scanner, and calc-main.c with "main()". This is in order to +# stress the use of the generated parser header. To avoid code +# duplication, AT_CALC_LEX and AT_CALC_MAIN contain the body of these +# two later files. m4_define([_AT_DATA_CALC_Y], [m4_if([$1$2$3], $[1]$[2]$[3], [], [m4_fatal([$0: Invalid arguments: $@])])dnl + +m4_pushdef([AT_CALC_MAIN], +[#include +#if HAVE_UNISTD_H +# include +#else +# undef alarm +# define alarm(seconds) /* empty */ +#endif + +AT_SKEL_CC_IF([[ +/* A C++ ]AT_NAME_PREFIX[parse that simulates the C signature. */ +int +]AT_NAME_PREFIX[parse (]AT_PARAM_IF([semantic_value *result, int *count]))[ +{ + ]AT_NAME_PREFIX[::parser parser]AT_PARAM_IF([ (result, count)])[; +#if YYDEBUG + parser.set_debug_level (1); +#endif + return parser.parse (); +} +]])[ + +semantic_value global_result = 0; +int global_count = 0; + +/* A C main function. */ +int +main (int argc, const char **argv) +{ + semantic_value result = 0; + int count = 0; + int status; + + /* This used to be alarm (10), but that isn't enough time for + a July 1995 vintage DEC Alphastation 200 4/100 system, + according to Nelson H. F. Beebe. 100 seconds is enough. */ + alarm (100); + + if (argc == 2) + input = fopen (argv[1], "r"); + else + input = stdin; + + if (!input) + { + perror (argv[1]); + return 3; + } + +]AT_SKEL_CC_IF([], [m4_bmatch([$4], [%debug], +[ ]AT_NAME_PREFIX[debug = 1;])])[ + status = ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([[&result, &count]])[); + if (fclose (input)) + perror ("fclose"); + assert (global_result == result); + assert (global_count == count); + return status; +} +]]) + + m4_pushdef([AT_CALC_LEX], [[#include -int ]AT_NAME_PREFIX[lex (]AT_LEX_FORMALS[); -static int get_char (]AT_LEX_FORMALS[); -static void unget_char (]AT_LEX_PRE_FORMALS[ int c); +]AT_YYLEX_DECLARE_EXTERN[ +static int get_char (]AT_YYLEX_FORMALS[); +static void unget_char (]AT_YYLEX_PRE_FORMALS[ int c); ]AT_LOCATION_IF([ static YYLTYPE last_yylloc; ])[ static int -get_char (]AT_LEX_FORMALS[) +get_char (]AT_YYLEX_FORMALS[) { int res = getc (input); ]AT_USE_LEX_ARGS[; @@ -65,7 +134,7 @@ get_char (]AT_LEX_FORMALS[) } static void -unget_char (]AT_LEX_PRE_FORMALS[ int c) +unget_char (]AT_YYLEX_PRE_FORMALS[ int c) { ]AT_USE_LEX_ARGS[; ]AT_LOCATION_IF([ @@ -76,26 +145,26 @@ unget_char (]AT_LEX_PRE_FORMALS[ int c) } static int -read_signed_integer (]AT_LEX_FORMALS[) +read_signed_integer (]AT_YYLEX_FORMALS[) { - int c = get_char (]AT_LEX_ARGS[); + int c = get_char (]AT_YYLEX_ARGS[); int sign = 1; int n = 0; ]AT_USE_LEX_ARGS[; if (c == '-') { - c = get_char (]AT_LEX_ARGS[); + c = get_char (]AT_YYLEX_ARGS[); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); - c = get_char (]AT_LEX_ARGS[); + c = get_char (]AT_YYLEX_ARGS[); } - unget_char (]AT_LEX_PRE_ARGS[ c); + unget_char (]AT_YYLEX_PRE_ARGS[ c); return sign * n; } @@ -107,8 +176,7 @@ read_signed_integer (]AT_LEX_FORMALS[) | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ -int -]AT_NAME_PREFIX[lex (]AT_LEX_FORMALS[) +]AT_YYLEX_PROTOTYPE[ { static int init = 1; int c; @@ -130,13 +198,13 @@ int AT_LOC_FIRST_LINE = AT_LOC_LAST_LINE; ])[ } - while ((c = get_char (]AT_LEX_ARGS[)) == ' ' || c == '\t'); + while ((c = get_char (]AT_YYLEX_ARGS[)) == ' ' || c == '\t'); /* process numbers */ if (c == '.' || isdigit (c)) { - unget_char (]AT_LEX_PRE_ARGS[ c); - ]AT_VAL[.ival = read_signed_integer (]AT_LEX_ARGS[); + unget_char (]AT_YYLEX_PRE_ARGS[ c); + ]AT_VAL[.ival = read_signed_integer (]AT_YYLEX_ARGS[); return ]AT_TOKEN_PREFIX[NUM; } @@ -198,7 +266,9 @@ AT_SKEL_CC_IF( { #include /* The input. */ -extern FILE *input;]AT_SKEL_CC_IF([[ +extern FILE *input; +extern semantic_value global_result; +extern int global_count;]AT_SKEL_CC_IF([[ #ifndef YYLTYPE # define YYLTYPE ]AT_NAME_PREFIX[::parser::location_type #endif @@ -208,30 +278,18 @@ extern FILE *input;]AT_SKEL_CC_IF([[ %code { #include -#include #include -#if HAVE_UNISTD_H -# include -#else -# undef alarm -# define alarm(seconds) /* empty */ -#endif #define USE(Var) FILE *input; -static semantic_value global_result = 0; -static int global_count = 0; static int power (int base, int exponent); ]AT_SKEL_CC_IF(, -[/* yyerror receives the location if: - - %location & %pure & %glr - - %location & %pure & %yacc & %parse-param. */ -static void yyerror (AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ]) +[static void yyerror (AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ]) AT_PARAM_IF([semantic_value *result, int *count, ]) const char *s );])[ -int yylex (]AT_LEX_FORMALS[); +]AT_YYLEX_DECLARE_EXTERN[ } ]AT_SKEL_CC_IF([AT_LOCATION_IF([AT_LOCATION_TYPE_IF([], [ @@ -289,6 +347,16 @@ exp: ; %% +static int +power (int base, int exponent) +{ + int res = 1; + assert (0 <= exponent); + for (/* Niente */; exponent; --exponent) + res *= base; + return res; +} + ]AT_SKEL_CC_IF( [AT_LOCATION_TYPE_IF([[ std::ostream& @@ -302,25 +370,7 @@ exp: return o; } ]]) - -/* A C++ error reporting function. */ -void -AT_NAME_PREFIX::parser::error (AT_LOCATION_IF([const location_type& l, ])const std::string& m) -{ - std::cerr << AT_LOCATION_IF([l << ": " << ])m << std::endl; -} - -/* A C++ yyparse that simulates the C signature. */ -int -yyparse (AT_PARAM_IF([semantic_value *result, int *count])) -{ - AT_NAME_PREFIX::parser parser[]AT_PARAM_IF([ (result, count)]); -#if YYDEBUG - parser.set_debug_level (1); -#endif - return parser.parse (); -} -], +AT_YYERROR_DEFINE], [/* A C error reporting function. */ static void yyerror (AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ]) @@ -341,59 +391,21 @@ AT_YYERROR_SEES_LOC_IF([ fprintf (stderr, "%s\n", s); }])[ -]AT_DEFINES_IF(, [AT_CALC_LEX])[ - -static int -power (int base, int exponent) -{ - int res = 1; - assert (0 <= exponent); - for (/* Niente */; exponent; --exponent) - res *= base; - return res; -} - - -/* A C main function. */ -int -main (int argc, const char **argv) -{ - semantic_value result = 0; - int count = 0; - int status; - - /* This used to be alarm (10), but that isn't enough time for - a July 1995 vintage DEC Alphastation 200 4/100 system, - according to Nelson H. F. Beebe. 100 seconds is enough. */ - alarm (100); - - if (argc == 2) - input = fopen (argv[1], "r"); - else - input = stdin; - - if (!input) - { - perror (argv[1]); - return 3; - } - -]AT_SKEL_CC_IF([], [m4_bmatch([$4], [%debug], -[ yydebug = 1;])])[ - status = yyparse (]AT_PARAM_IF([[&result, &count]])[); - if (fclose (input)) - perror ("fclose"); - if (global_result != result) - abort (); - if (global_count != count) - abort (); - return status; -} +]AT_DEFINES_IF([], +[AT_CALC_LEX +AT_CALC_MAIN])[ ]]) + AT_DEFINES_IF([AT_DATA_SOURCE([[calc-lex.c]AT_SKEL_CC_IF([[c]])], [[#include "calc.h]AT_SKEL_CC_IF([[h]])[" -]AT_CALC_LEX])]) +]AT_CALC_LEX]) +AT_DATA_SOURCE([[calc-main.c]AT_SKEL_CC_IF([[c]])], +[[#include "calc.h]AT_SKEL_CC_IF([[h]])[" + +]AT_CALC_MAIN]) +]) +m4_popdef([AT_CALC_MAIN]) m4_popdef([AT_CALC_LEX]) ])# _AT_DATA_CALC_Y @@ -492,21 +504,20 @@ AT_CHECK([cat stderr], 0, [expout]) ]) -# AT_CHECK_CALC([BISON-OPTIONS, [EXPECTED-TO-FAIL]]) -# -------------------------------------------------- +# AT_CHECK_CALC([BISON-OPTIONS]) +# ------------------------------ # Start a testing chunk which compiles `calc' grammar with # BISON-OPTIONS, and performs several tests over the parser. -# However, if EXPECTED-TO-FAIL is nonempty, this test is expected to fail. m4_define([AT_CHECK_CALC], -[# We use integers to avoid dependencies upon the precision of doubles. -AT_SETUP([Calculator $1]) +[m4_ifval([$2], [m4_fatal([$0: expected a single argument])]) -m4_ifval([$2], [AT_CHECK([exit 77])]) +# We use integers to avoid dependencies upon the precision of doubles. +AT_SETUP([Calculator $1]) AT_BISON_OPTION_PUSHDEFS([$1]) AT_DATA_CALC_Y([$1]) -AT_FULL_COMPILE([calc], [AT_DEFINES_IF([[lex]])]) +AT_FULL_COMPILE([calc], AT_DEFINES_IF([[lex], [main]])) # Test the priorities. _AT_CHECK_CALC([$1],