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. 43m4_define([_AT_DATA_CALC_Y], 44[m4_if([$1$2$3], $[1]$[2]$[3], [], 45 [m4_fatal([$0: Invalid arguments: $@])])dnl 46 47m4_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 56AT_SKEL_CC_IF([[ 57/* A C++ ]AT_NAME_PREFIX[parse that simulates the C signature. */ 58int 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 69semantic_value global_result = 0; 70int global_count = 0; 71 72/* A C main function. */ 73int 74main (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 108m4_pushdef([AT_CALC_LEX], 109[[#include <ctype.h> 110 111]AT_YYLEX_DECLARE_EXTERN[ 112static int get_char (]AT_YYLEX_FORMALS[); 113static void unget_char (]AT_YYLEX_PRE_FORMALS[ int c); 114 115]AT_LOCATION_IF([ 116static AT_YYLTYPE last_yylloc; 117])[ 118static int 119get_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 136static void 137unget_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 147static int 148read_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 209AT_DATA_GRAMMAR([calc.y], 210[[/* Infix notation calculator--calc */ 211]$4 212AT_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 271FILE *input; 272static 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%% 298input: 299 line 300| input line { ]AT_PARAM_IF([++*count; ++global_count;])[ } 301; 302 303line: 304 '\n' 305| exp '\n' { ]AT_PARAM_IF([*result = global_result = $1], [USE ($1)])[; } 306; 307 308exp: 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 329static int 330power (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 355AT_CALC_MAIN])]) 356 357AT_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]) 361AT_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]) 366m4_popdef([AT_CALC_MAIN]) 367m4_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'. 375m4_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. 392m4_define([_AT_CHECK_CALC], 393[AT_DATA([[input]], 394[[$2 395]]) 396AT_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. 421m4_define([_AT_CHECK_CALC_ERROR], 422[m4_bmatch([$3], [^/], 423 [AT_PARSER_CHECK([./calc $3], $2, [], [stderr])], 424 [AT_DATA([[input]], 425[[$3 426]]) 427AT_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. 432sed '/^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 447mv at-stderr stderr 448# 2. Create the reference error message. 449AT_DATA([[expout]], 450[$5 451]) 452# 3. If locations are not used, remove them. 453AT_YYERROR_SEES_LOC_IF([], 454[[sed 's/^[-0-9.]*: //' expout >at-expout 455mv at-expout expout]]) 456# 4. If error-verbose is not used, strip the`, unexpected....' part. 457m4_bmatch([$1], [%error-verbose], [], 458[[sed 's/syntax error, .*$/syntax error/' expout >at-expout 459mv at-expout expout]]) 460# 5. Check 461AT_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. 469m4_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. 486m4_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. 490AT_SETUP([Calculator $1]) 491 492AT_BISON_OPTION_PUSHDEFS([$1]) 493 494AT_DATA_CALC_Y([$1]) 495AT_FULL_COMPILE([calc], AT_DEFINES_IF([[lex], [main]])) 496AT_CHECK_SPACES([calc.AT_SKEL_CC_IF([cc], [c])]) 497AT_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 5021 + 2 * -3 = -5 503 504-1^2 = -1 505(-1)^2 = 1 506 507---1 = -1 508 5091 - 2 - 3 = -4 5101 - (2 - 3) = 2 511 5122^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 '!' 5541.18: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 5551.23: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 5561.41: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 557calc: 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 563calc: 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 '!' 5661.12: syntax error, unexpected number 567calc: 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 '!' 5731.10: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 5741.16: syntax error, unexpected '*', expecting number or '-' or '(' or '!']) 575 576AT_BISON_OPTION_POPDEFS 577 578AT_CLEANUP 579])# AT_CHECK_CALC 580 581 582 583 584# ------------------------ # 585# Simple LALR Calculator. # 586# ------------------------ # 587 588AT_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. 594m4_define([AT_CHECK_CALC_LALR], 595[AT_CHECK_CALC($@)]) 596 597AT_CHECK_CALC_LALR() 598 599AT_CHECK_CALC_LALR([%defines]) 600AT_CHECK_CALC_LALR([%locations]) 601 602AT_CHECK_CALC_LALR([%name-prefix="calc"]) dnl test deprecated `=' 603AT_CHECK_CALC_LALR([%verbose]) 604AT_CHECK_CALC_LALR([%yacc]) 605AT_CHECK_CALC_LALR([%error-verbose]) 606 607AT_CHECK_CALC_LALR([%define api.pure full %locations]) 608AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full %locations]) 609AT_CHECK_CALC_LALR([%error-verbose %locations]) 610 611AT_CHECK_CALC_LALR([%error-verbose %locations %defines %name-prefix "calc" %verbose %yacc]) 612AT_CHECK_CALC_LALR([%error-verbose %locations %defines %define api.prefix "calc" %verbose %yacc]) 613 614AT_CHECK_CALC_LALR([%debug]) 615AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) 616AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc]) 617 618AT_CHECK_CALC_LALR([%define api.pure full %verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) 619AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full %verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc]) 620 621AT_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 628AT_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. 634m4_define([AT_CHECK_CALC_GLR], 635[AT_CHECK_CALC([%glr-parser] $@)]) 636 637 638AT_CHECK_CALC_GLR() 639 640AT_CHECK_CALC_GLR([%defines]) 641AT_CHECK_CALC_GLR([%locations]) 642AT_CHECK_CALC_GLR([%name-prefix "calc"]) 643AT_CHECK_CALC_GLR([%define api.prefix "calc"]) 644AT_CHECK_CALC_GLR([%verbose]) 645AT_CHECK_CALC_GLR([%yacc]) 646AT_CHECK_CALC_GLR([%error-verbose]) 647 648AT_CHECK_CALC_GLR([%define api.pure %locations]) 649AT_CHECK_CALC_GLR([%error-verbose %locations]) 650 651AT_CHECK_CALC_GLR([%error-verbose %locations %defines %name-prefix "calc" %verbose %yacc]) 652 653AT_CHECK_CALC_GLR([%debug]) 654AT_CHECK_CALC_GLR([%error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) 655AT_CHECK_CALC_GLR([%error-verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc]) 656 657AT_CHECK_CALC_GLR([%define api.pure %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) 658 659AT_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}]) 660AT_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 667AT_BANNER([[Simple LALR(1) C++ Calculator.]]) 668 669# First let's try using %skeleton 670AT_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. 676m4_define([AT_CHECK_CALC_LALR1_CC], 677[AT_CHECK_CALC([%language "C++" %defines %locations] $@)]) 678 679AT_CHECK_CALC_LALR1_CC([]) 680AT_CHECK_CALC_LALR1_CC([%define api.location.type Span]) 681AT_CHECK_CALC_LALR1_CC([%error-verbose %name-prefix "calc" %verbose %yacc]) 682AT_CHECK_CALC_LALR1_CC([%error-verbose %define api.prefix "calc" %verbose %yacc]) 683AT_CHECK_CALC_LALR1_CC([%error-verbose %debug %name-prefix "calc" %verbose %yacc]) 684 685AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %define api.prefix "calc" %verbose %yacc]) 686 687AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}]) 688AT_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 696AT_BANNER([[Simple GLR C++ Calculator.]]) 697 698# Again, we try also using %skeleton. 699AT_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. 705m4_define([AT_CHECK_CALC_GLR_CC], 706[AT_CHECK_CALC([%language "C++" %glr-parser %defines %locations] $@)]) 707 708AT_CHECK_CALC_GLR_CC([]) 709AT_CHECK_CALC_GLR_CC([%define api.location.type Span]) 710AT_CHECK_CALC_GLR_CC([%error-verbose %name-prefix "calc" %verbose %yacc]) 711AT_CHECK_CALC_GLR_CC([%error-verbose %define api.prefix "calc" %verbose %yacc]) 712 713AT_CHECK_CALC_GLR_CC([%debug]) 714AT_CHECK_CALC_GLR_CC([%error-verbose %debug %name-prefix "calc" %verbose %yacc]) 715 716AT_CHECK_CALC_GLR_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc]) 717 718AT_CHECK_CALC_GLR_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}]) 719AT_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