1 # Java tests for simple calculator. -*- Autotest -*- 2 3 # Copyright (C) 2007-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([[Java Calculator.]]) 19 20 21 # ------------------------- # 22 # Helping Autotest macros. # 23 # ------------------------- # 24 25 26 # _AT_DATA_JAVA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES]) 27 # ---------------------------------------------------------------------- 28 # Produce `calc.y'. Don't call this macro directly, because it contains 29 # some occurrences of `$1' etc. which will be interpreted by m4. So 30 # you should call it with $1, $2, and $3 as arguments, which is what 31 # AT_DATA_JAVA_CALC_Y does. 32 m4_define([_AT_DATA_JAVA_CALC_Y], 33 [m4_if([$1$2$3], $[1]$[2]$[3], [], 34 [m4_fatal([$0: Invalid arguments: $@])])dnl 35 AT_BISON_OPTION_PUSHDEFS([%language "Java" $4]) 36 AT_DATA([Calc.y], 37 [[/* Infix notation calculator--calc */ 38 %language "Java" 39 %name-prefix "Calc" 40 %define parser_class_name "Calc" 41 %define public 42 43 ]$4[ 44 45 %code imports { 46 import java.io.StreamTokenizer; 47 import java.io.InputStream; 48 import java.io.InputStreamReader; 49 import java.io.Reader; 50 import java.io.IOException; 51 } 52 53 /* Bison Declarations */ 54 %token <Integer> NUM "number" 55 %type <Integer> exp 56 57 %nonassoc '=' /* comparison */ 58 %left '-' '+' 59 %left '*' '/' 60 %left NEG /* negation--unary minus */ 61 %right '^' /* exponentiation */ 62 63 /* Grammar follows */ 64 %% 65 input: 66 line 67 | input line 68 ; 69 70 line: 71 '\n' 72 | exp '\n' 73 | error '\n' 74 ; 75 76 exp: 77 NUM { $$ = $1; } 78 | exp '=' exp 79 { 80 if ($1.intValue () != $3.intValue ()) 81 yyerror (]AT_LOCATION_IF([[@$,]])[ "calc: error: " + $1 + " != " + $3); 82 } 83 | exp '+' exp { $$ = new Integer ($1.intValue () + $3.intValue ()); } 84 | exp '-' exp { $$ = new Integer ($1.intValue () - $3.intValue ()); } 85 | exp '*' exp { $$ = new Integer ($1.intValue () * $3.intValue ()); } 86 | exp '/' exp { $$ = new Integer ($1.intValue () / $3.intValue ()); } 87 | '-' exp %prec NEG { $$ = new Integer (-$2.intValue ()); } 88 | exp '^' exp { $$ = new Integer ((int) 89 Math.pow ($1.intValue (), 90 $3.intValue ())); } 91 | '(' exp ')' { $$ = $2; } 92 | '(' error ')' { $$ = new Integer (1111); } 93 | '!' { $$ = new Integer (0); return YYERROR; } 94 | '-' error { $$ = new Integer (0); return YYERROR; } 95 ; 96 97 ]AT_LEXPARAM_IF([[ 98 %code lexer { 99 ]], 100 [[ 101 %% 102 class CalcLexer implements Calc.Lexer { 103 ]])[ 104 StreamTokenizer st; 105 106 public ]AT_LEXPARAM_IF([[YYLexer]], [[CalcLexer]]) (InputStream is) 107 { 108 st = new StreamTokenizer (new InputStreamReader (is)); 109 st.resetSyntax (); 110 st.eolIsSignificant (true); 111 st.whitespaceChars (9, 9); 112 st.whitespaceChars (32, 32); 113 st.wordChars (48, 57); 114 } 115 116 AT_LOCATION_IF([[ 117 Position yypos = new Position (1, 0); 118 119 public Position getStartPos() { 120 return yypos; 121 } 122 123 public Position getEndPos() { 124 return yypos; 125 } 126 ]])[ 127 ]AT_YYERROR_DEFINE[ 128 129 Integer yylval; 130 131 public Object getLVal() { 132 return yylval; 133 } 134 135 public int yylex () throws IOException { 136 int ttype = st.nextToken (); 137 ]AT_LOCATION_IF([[yypos = new Position (yypos.lineno (), 138 yypos.token () + 1);]])[ 139 if (ttype == st.TT_EOF) 140 return Calc.EOF; 141 142 else if (ttype == st.TT_EOL) 143 { 144 ]AT_LOCATION_IF([[yypos = new Position (yypos.lineno () + 1, 0);]])[ 145 return (int) '\n'; 146 } 147 148 else if (ttype == st.TT_WORD) 149 { 150 yylval = new Integer (st.sval); 151 return Calc.NUM; 152 } 153 154 else 155 return st.ttype; 156 } 157 158 159 ]AT_LEXPARAM_IF([[ 160 }; 161 %%]], [[ 162 }]]) 163 164 [ 165 class Position { 166 public int line; 167 public int token; 168 169 public Position () 170 { 171 line = 0; 172 token = 0; 173 } 174 175 public Position (int l, int t) 176 { 177 line = l; 178 token = t; 179 } 180 181 public boolean equals (Position l) 182 { 183 return l.line == line && l.token == token; 184 } 185 186 public String toString () 187 { 188 return Integer.toString (line) + "." + Integer.toString(token); 189 } 190 191 public int lineno () 192 { 193 return line; 194 } 195 196 public int token () 197 { 198 return token; 199 } 200 } 201 202 ]]) 203 AT_BISON_OPTION_POPDEFS 204 ])# _AT_DATA_JAVA_CALC_Y 205 206 207 # AT_DATA_CALC_Y([BISON-OPTIONS]) 208 # ------------------------------- 209 # Produce `calc.y'. 210 m4_define([AT_DATA_JAVA_CALC_Y], 211 [_AT_DATA_JAVA_CALC_Y($[1], $[2], $[3], [$1]) 212 ]) 213 214 215 # _AT_CHECK_JAVA_CALC_ERROR(BISON-OPTIONS, INPUT, 216 # [VERBOSE-AND-LOCATED-ERROR-MESSAGE]) 217 # -------------------------------------------------------------- 218 # Run `calc' on INPUT, and expect a `syntax error' message. 219 # 220 # If INPUT starts with a slash, it is used as absolute input file name, 221 # otherwise as contents. 222 # 223 # The VERBOSE-AND-LOCATED-ERROR-MESSAGE is stripped of locations 224 # and expected tokens if necessary, and compared with the output. 225 m4_define([_AT_CHECK_JAVA_CALC_ERROR], 226 [m4_bmatch([$2], [^/], 227 [AT_JAVA_PARSER_CHECK([Calc < $2], 0, [], [stderr])], 228 [AT_DATA([[input]], 229 [[$2 230 ]]) 231 AT_JAVA_PARSER_CHECK([Calc < input], 0, [], [stderr])]) 232 233 # Normalize the observed and expected error messages, depending upon the 234 # options. 235 # 1. Create the reference error message. 236 AT_DATA([[expout]], 237 [$3 238 ]) 239 # 2. If locations are not used, remove them. 240 AT_YYERROR_SEES_LOC_IF([], 241 [[sed 's/^[-0-9.]*: //' expout >at-expout 242 mv at-expout expout]]) 243 # 3. If error-verbose is not used, strip the`, unexpected....' part. 244 m4_bmatch([$1], [%error-verbose], [], 245 [[sed 's/syntax error, .*$/syntax error/' expout >at-expout 246 mv at-expout expout]]) 247 # 4. Check 248 AT_CHECK([cat stderr], 0, [expout]) 249 ]) 250 251 # _AT_CHECK_JAVA_CALC([BISON-DIRECTIVES], [BISON-CODE]) 252 # ----------------------------------------------------------------------- 253 # Start a testing chunk which compiles `calc' grammar with 254 # BISON-DIRECTIVES, and performs several tests over the parser. 255 m4_define([_AT_CHECK_JAVA_CALC], 256 [# We use integers to avoid dependencies upon the precision of doubles. 257 AT_SETUP([Calculator $1]) 258 259 AT_BISON_OPTION_PUSHDEFS([$1]) 260 261 AT_DATA_JAVA_CALC_Y([$1 262 %code { 263 $2 264 }]) 265 266 AT_BISON_CHECK([-o Calc.java Calc.y]) 267 AT_JAVA_COMPILE([Calc.java]) 268 269 # Test the priorities. 270 AT_DATA([[input]], 271 [[1 + 2 * 3 = 7 272 1 + 2 * -3 = -5 273 274 -1^2 = -1 275 (-1)^2 = 1 276 277 ---1 = -1 278 279 1 - 2 - 3 = -4 280 1 - (2 - 3) = 2 281 282 2^2^3 = 256 283 (2^2)^3 = 64 284 ]]) 285 AT_JAVA_PARSER_CHECK([Calc < input], 0, [], [stderr]) 286 287 288 # Some syntax errors. 289 _AT_CHECK_JAVA_CALC_ERROR([$1], [0 0], 290 [1.2: syntax error, unexpected number]) 291 _AT_CHECK_JAVA_CALC_ERROR([$1], [1//2], 292 [1.3: syntax error, unexpected '/', expecting number or '-' or '(' or '!']) 293 _AT_CHECK_JAVA_CALC_ERROR([$1], [error], 294 [1.1: syntax error, unexpected $undefined]) 295 _AT_CHECK_JAVA_CALC_ERROR([$1], [1 = 2 = 3], 296 [1.4: syntax error, unexpected '=']) 297 _AT_CHECK_JAVA_CALC_ERROR([$1], [ 298 +1], 299 [2.1: syntax error, unexpected '+']) 300 # Exercise error messages with EOF: work on an empty file. 301 _AT_CHECK_JAVA_CALC_ERROR([$1], [/dev/null], 302 [1.1: syntax error, unexpected end of input]) 303 304 # Exercise the error token: without it, we die at the first error, 305 # hence be sure to 306 # 307 # - have several errors which exercise different shift/discardings 308 # - (): nothing to pop, nothing to discard 309 # - (1 + 1 + 1 +): a lot to pop, nothing to discard 310 # - (* * *): nothing to pop, a lot to discard 311 # - (1 + 2 * *): some to pop and discard 312 # 313 # - test the action associated to `error' 314 # 315 # - check the lookahead that triggers an error is not discarded 316 # when we enter error recovery. Below, the lookahead causing the 317 # first error is ")", which is needed to recover from the error and 318 # produce the "0" that triggers the "0 != 1" error. 319 # 320 _AT_CHECK_JAVA_CALC_ERROR([$1], 321 [() + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1], 322 [1.2: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 323 1.11: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 324 1.14: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 325 1.24: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 326 1.1-1.27: calc: error: 4444 != 1]) 327 328 # The same, but this time exercising explicitly triggered syntax errors. 329 # POSIX says the lookahead causing the error should not be discarded. 330 _AT_CHECK_JAVA_CALC_ERROR([$1], [(!) + (0 0) = 1], 331 [1.7: syntax error, unexpected number 332 1.1-1.10: calc: error: 2222 != 1]) 333 _AT_CHECK_JAVA_CALC_ERROR([$1], [(- *) + (0 0) = 1], 334 [1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 335 1.8: syntax error, unexpected number 336 1.1-1.11: calc: error: 2222 != 1]) 337 AT_BISON_OPTION_POPDEFS 338 339 AT_CLEANUP 340 ])# _AT_CHECK_JAVA_CALC 341 342 343 # AT_CHECK_JAVA_CALC([BISON-DIRECTIVES]) 344 # -------------------------------------------------------- 345 # Start a testing chunk which compiles `calc' grammar with 346 # BISON-DIRECTIVES, and performs several tests over the parser. 347 # Run the test with and without %error-verbose. 348 m4_define([AT_CHECK_JAVA_CALC], 349 [_AT_CHECK_JAVA_CALC([$1], [$2]) 350 _AT_CHECK_JAVA_CALC([%error-verbose $1], [$2]) 351 _AT_CHECK_JAVA_CALC([%locations $1], [$2]) 352 _AT_CHECK_JAVA_CALC([%error-verbose %locations $1], [$2]) 353 ])# AT_CHECK_JAVA_CALC 354 355 356 # ------------------------ # 357 # Simple LALR Calculator. # 358 # ------------------------ # 359 360 AT_CHECK_JAVA_CALC([], [[ 361 public static void main (String args[]) throws IOException 362 { 363 CalcLexer l = new CalcLexer (System.in); 364 Calc p = new Calc (l); 365 p.parse (); 366 } 367 ]]) 368 369 AT_CHECK_JAVA_CALC([%lex-param { InputStream is } ], [[ 370 public static void main (String args[]) throws IOException 371 { 372 new Calc (System.in).parse (); 373 } 374 ]]) 375 376 377 378 # -----------------# 379 # Java Directives. # 380 # -----------------# 381 382 AT_BANNER([Java Parameters.]) 383 384 385 # AT_CHECK_JAVA_MINIMAL([DIRECTIVES], [PARSER_ACTION], [POSITION_CLASS]) 386 # ---------------------------------------------------------------------- 387 # Check that a mininal parser with DIRECTIVES compiles in Java. 388 # Put the Java code in YYParser.java. 389 m4_define([AT_CHECK_JAVA_MINIMAL], 390 [ 391 AT_DATA([[YYParser.y]], [ 392 %language "Java" 393 %locations 394 %debug 395 %error-verbose 396 %token-table 397 $1 398 %% 399 start: "end" {$2}; 400 %% 401 class m4_default([$3], [Position]) {} 402 ]) 403 AT_BISON_CHECK([[YYParser.y]]) 404 AT_CHECK([[grep '[mb]4_' YYParser.y]], [1], [ignore]) 405 AT_JAVA_COMPILE([[YYParser.java]]) 406 ]) 407 408 409 # AT_CHECK_JAVA_MINIMAL_W_LEXER([1:DIRECTIVES], [2:LEX_THROWS], 410 # [3:YYLEX_ACTION], [4:LEXER_BODY], [5:PARSER_ACTION], [6:STYPE], 411 # [7:POSITION_TYPE], [8:LOCATION_TYPE]) 412 # --------------------------------------------------------------------- 413 # Check that a mininal parser with DIRECTIVES and a "%code lexer". 414 # YYLEX is the body of yylex () which throws LEX_THROW. 415 # compiles in Java. 416 m4_define([AT_CHECK_JAVA_MINIMAL_W_LEXER], 417 [AT_CHECK_JAVA_MINIMAL([$1 418 419 %code lexer 420 { 421 m4_default([$6], [Object]) yylval; 422 public m4_default([$6], [Object]) getLVal() { return yylval; } 423 424 public m4_default([$7], [Position]) getStartPos() { return null; } 425 public m4_default([$7], [Position]) getEndPos() { return null; } 426 427 public void yyerror (m4_default([$8], [Location]) loc, String s) 428 { 429 System.err.println (loc + ": " + s); 430 } 431 432 public int yylex ()$2 433 { 434 $3 435 } 436 437 $4 438 }], [$5], [$7])]) 439 440 441 # AT_CHECK_JAVA_GREP([LINE], [COUNT=1]) 442 # ------------------------------------- 443 # Check that YYParser.java contains exactly COUNT lines matching ^LINE$ 444 # with grep. 445 m4_define([AT_CHECK_JAVA_GREP], 446 [AT_CHECK([grep -c '^$1$' YYParser.java], [], [m4_default([$2], [1]) 447 ]) 448 ]) 449 450 451 # ----------------------------------- # 452 # Java parser class and package names # 453 # ----------------------------------- # 454 455 AT_SETUP([Java parser class and package names]) 456 457 AT_CHECK_JAVA_MINIMAL([]) 458 AT_CHECK_JAVA_GREP([[class YYParser]]) 459 460 AT_CHECK_JAVA_MINIMAL([[%name-prefix "Prefix"]]) 461 AT_CHECK_JAVA_GREP([[class PrefixParser]]) 462 463 AT_CHECK_JAVA_MINIMAL([[%define parser_class_name "ParserClassName"]]) 464 AT_CHECK_JAVA_GREP([[class ParserClassName]]) 465 466 AT_CHECK_JAVA_MINIMAL([[%define package "user_java_package"]]) 467 AT_CHECK_JAVA_GREP([[package user_java_package;]]) 468 469 AT_CLEANUP 470 471 472 # --------------------------- # 473 # Java parser class modifiers # 474 # --------------------------- # 475 476 AT_SETUP([Java parser class modifiers]) 477 478 AT_CHECK_JAVA_MINIMAL([[%define abstract]]) 479 AT_CHECK_JAVA_GREP([[abstract class YYParser]]) 480 481 AT_CHECK_JAVA_MINIMAL([[%define final]]) 482 AT_CHECK_JAVA_GREP([[final class YYParser]]) 483 484 AT_CHECK_JAVA_MINIMAL([[%define strictfp]]) 485 AT_CHECK_JAVA_GREP([[strictfp class YYParser]]) 486 487 AT_CHECK_JAVA_MINIMAL([[ 488 %define abstract 489 %define strictfp]]) 490 AT_CHECK_JAVA_GREP([[abstract strictfp class YYParser]]) 491 492 AT_CHECK_JAVA_MINIMAL([[ 493 %define final 494 %define strictfp]]) 495 AT_CHECK_JAVA_GREP([[final strictfp class YYParser]]) 496 497 AT_CHECK_JAVA_MINIMAL([[%define public]]) 498 AT_CHECK_JAVA_GREP([[public class YYParser]]) 499 500 AT_CHECK_JAVA_MINIMAL([[ 501 %define public 502 %define abstract]]) 503 AT_CHECK_JAVA_GREP([[public abstract class YYParser]]) 504 505 AT_CHECK_JAVA_MINIMAL([[ 506 %define public 507 %define final]]) 508 AT_CHECK_JAVA_GREP([[public final class YYParser]]) 509 510 AT_CHECK_JAVA_MINIMAL([[ 511 %define public 512 %define strictfp]]) 513 AT_CHECK_JAVA_GREP([[public strictfp class YYParser]]) 514 515 AT_CHECK_JAVA_MINIMAL([[ 516 %define public 517 %define abstract 518 %define strictfp]]) 519 AT_CHECK_JAVA_GREP([[public abstract strictfp class YYParser]]) 520 521 AT_CHECK_JAVA_MINIMAL([[ 522 %define public 523 %define final 524 %define strictfp]]) 525 AT_CHECK_JAVA_GREP([[public final strictfp class YYParser]]) 526 527 AT_CLEANUP 528 529 530 # ---------------------------------------- # 531 # Java parser class extends and implements # 532 # ---------------------------------------- # 533 534 AT_SETUP([Java parser class extends and implements]) 535 536 AT_CHECK_JAVA_MINIMAL([[%define extends "Thread"]]) 537 AT_CHECK_JAVA_GREP([[class YYParser extends Thread]]) 538 539 AT_CHECK_JAVA_MINIMAL([[%define implements "Cloneable"]]) 540 AT_CHECK_JAVA_GREP([[class YYParser implements Cloneable]]) 541 542 AT_CHECK_JAVA_MINIMAL([[ 543 %define extends "Thread" 544 %define implements "Cloneable"]]) 545 AT_CHECK_JAVA_GREP([[class YYParser extends Thread implements Cloneable]]) 546 547 AT_CLEANUP 548 549 550 # -------------------------------- # 551 # Java %parse-param and %lex-param # 552 # -------------------------------- # 553 554 AT_SETUP([Java %parse-param and %lex-param]) 555 556 AT_CHECK_JAVA_MINIMAL([]) 557 AT_CHECK_JAVA_GREP([[ *public YYParser (Lexer yylexer) {]]) 558 559 AT_CHECK_JAVA_MINIMAL([[%parse-param {int parse_param1}]]) 560 AT_CHECK_JAVA_GREP([[ *protected final int parse_param1;]]) 561 AT_CHECK_JAVA_GREP([[ *public YYParser (Lexer yylexer, *int parse_param1) {]]) 562 AT_CHECK_JAVA_GREP([[[ ]*this.parse_param1 = parse_param1;]]) 563 564 AT_CHECK_JAVA_MINIMAL([[ 565 %parse-param {int parse_param1} 566 %parse-param {long parse_param2}]]) 567 AT_CHECK_JAVA_GREP([[ *protected final int parse_param1;]]) 568 AT_CHECK_JAVA_GREP([[ *protected final long parse_param2;]]) 569 AT_CHECK_JAVA_GREP([[ *public YYParser (Lexer yylexer, *int parse_param1, *long parse_param2) {]]) 570 AT_CHECK_JAVA_GREP([[[ ]*this.parse_param1 = parse_param1;]]) 571 AT_CHECK_JAVA_GREP([[[ ]*this.parse_param2 = parse_param2;]]) 572 573 AT_CHECK_JAVA_MINIMAL_W_LEXER([], [], [[return EOF;]]) 574 AT_CHECK_JAVA_GREP([[ *public YYParser () {]]) 575 AT_CHECK_JAVA_GREP([[ *protected YYParser (Lexer yylexer) {]]) 576 577 AT_CHECK_JAVA_MINIMAL_W_LEXER([[%parse-param {int parse_param1}]], 578 [], [[return EOF;]]) 579 AT_CHECK_JAVA_GREP([[ *protected final int parse_param1;]]) 580 AT_CHECK_JAVA_GREP([[ *public YYParser (int parse_param1) {]]) 581 AT_CHECK_JAVA_GREP([[ *protected YYParser (Lexer yylexer, *int parse_param1) {]]) 582 AT_CHECK_JAVA_GREP([[[ ]*this.parse_param1 = parse_param1;]], [2]) 583 584 AT_CHECK_JAVA_MINIMAL_W_LEXER([[ 585 %parse-param {int parse_param1} 586 %parse-param {long parse_param2}]], 587 [], [[return EOF;]]) 588 AT_CHECK_JAVA_GREP([[ *protected final int parse_param1;]]) 589 AT_CHECK_JAVA_GREP([[ *protected final long parse_param2;]]) 590 AT_CHECK_JAVA_GREP([[ *public YYParser (int parse_param1, *long parse_param2) {]]) 591 AT_CHECK_JAVA_GREP([[ *protected YYParser (Lexer yylexer, *int parse_param1, *long parse_param2) {]]) 592 AT_CHECK_JAVA_GREP([[[ ]*this.parse_param1 = parse_param1;]], [2]) 593 AT_CHECK_JAVA_GREP([[[ ]*this.parse_param2 = parse_param2;]], [2]) 594 595 AT_CHECK_JAVA_MINIMAL_W_LEXER([[%lex-param {char lex_param1}]], 596 [], [[return EOF;]], [[YYLexer (char lex_param1) {}]]) 597 AT_CHECK_JAVA_GREP([[ *public YYParser (char lex_param1) {]]) 598 AT_CHECK_JAVA_GREP([[.* = new YYLexer *(lex_param1);]]) 599 600 AT_CHECK_JAVA_MINIMAL_W_LEXER([[ 601 %lex-param {char lex_param1} 602 %lex-param {short lex_param2}]], 603 [], [[return EOF;]], [[YYLexer (char lex_param1, short lex_param2) {}]]) 604 AT_CHECK_JAVA_GREP([[ *public YYParser (char lex_param1, *short lex_param2) {]]) 605 AT_CHECK_JAVA_GREP([[.* = new YYLexer *(lex_param1, *lex_param2);]]) 606 607 AT_CHECK_JAVA_MINIMAL_W_LEXER([[ 608 %parse-param {int parse_param1} 609 %parse-param {long parse_param2} 610 %lex-param {char lex_param1} 611 %lex-param {short lex_param2}]], 612 [], [[return EOF;]], [[YYLexer (char lex_param1, short lex_param2) {}]]) 613 AT_CHECK_JAVA_GREP([[ *protected final int parse_param1;]]) 614 AT_CHECK_JAVA_GREP([[ *protected final long parse_param2;]]) 615 AT_CHECK_JAVA_GREP([[ *public YYParser (char lex_param1, *short lex_param2, *int parse_param1, *long parse_param2) {]]) 616 AT_CHECK_JAVA_GREP([[.* = new YYLexer *(lex_param1, *lex_param2);]]) 617 AT_CHECK_JAVA_GREP([[ *protected YYParser (Lexer yylexer, *int parse_param1, *long parse_param2) {]]) 618 AT_CHECK_JAVA_GREP([[[ ]*this.parse_param1 = parse_param1;]], [2]) 619 AT_CHECK_JAVA_GREP([[[ ]*this.parse_param2 = parse_param2;]], [2]) 620 621 AT_CLEANUP 622 623 624 # ------------------------- # 625 # Java throw specifications # 626 # ------------------------- # 627 628 AT_SETUP([Java throws specifications]) 629 630 # %define throws - 0 1 2 631 # %define lex-throws - 0 1 2 632 # %code lexer 0 1 633 634 m4_define([AT_JT_lex_throws_define], [m4_case(AT_JT_lex_throws, 635 -1, [], 636 0, [[%define lex_throws ""]], 637 1, [[%define lex_throws "InterruptedException"]], 638 2, [[%define lex_throws "InterruptedException, IllegalAccessException"]])]) 639 640 m4_define([AT_JT_yylex_throws], [m4_case(AT_JT_lex_throws, 641 -1, [[ throws java.io.IOException]], 642 0, [], 643 1, [[ throws InterruptedException]], 644 2, [[ throws InterruptedException, IllegalAccessException]])]) 645 646 m4_define([AT_JT_yylex_action], [m4_case(AT_JT_lex_throws, 647 -1, [[throw new java.io.IOException();]], 648 0, [[return EOF;]], 649 1, [[throw new InterruptedException();]], 650 2, [[throw new IllegalAccessException();]])]) 651 652 653 m4_define([AT_JT_throws_define], [m4_case(AT_JT_throws, 654 -1, [], 655 0, [[%define throws ""]], 656 1, [[%define throws "ClassNotFoundException"]], 657 2, [[%define throws "ClassNotFoundException, InstantiationException"]])]) 658 659 m4_define([AT_JT_yyaction_throws], [m4_case(AT_JT_throws, 660 -1, [], 661 0, [], 662 1, [[ throws ClassNotFoundException]], 663 2, [[ throws ClassNotFoundException, InstantiationException]])]) 664 665 m4_define([AT_JT_parse_throws_2], [m4_case(AT_JT_throws, 666 -1, [], 667 0, [], 668 1, [[, ClassNotFoundException]], 669 2, [[, ClassNotFoundException, InstantiationException]])]) 670 671 m4_define([AT_JT_parse_throws], 672 [m4_if(m4_quote(AT_JT_yylex_throws), [], 673 [AT_JT_yyaction_throws], 674 [AT_JT_yylex_throws[]AT_JT_parse_throws_2])]) 675 676 m4_define([AT_JT_initial_action], [m4_case(AT_JT_throws, 677 -1, [], 678 0, [], 679 1, [[%initial-action {if (true) throw new ClassNotFoundException();}]], 680 2, [[%initial-action {if (true) throw new InstantiationException();}]])]) 681 682 m4_define([AT_JT_parse_action], [m4_case(AT_JT_throws, 683 -1, [], 684 0, [], 685 1, [[throw new ClassNotFoundException();]], 686 2, [[throw new ClassNotFoundException();]])]) 687 688 m4_for([AT_JT_lexer], 0, 1, 1, 689 [m4_for([AT_JT_lex_throws], -1, 2, 1, 690 [m4_for([AT_JT_throws], -1, 2, 1, 691 [m4_if(AT_JT_lexer, 0, 692 [AT_CHECK_JAVA_MINIMAL([ 693 AT_JT_throws_define 694 AT_JT_lex_throws_define 695 AT_JT_initial_action], 696 [AT_JT_parse_action])], 697 [AT_CHECK_JAVA_MINIMAL_W_LEXER([ 698 AT_JT_throws_define 699 AT_JT_lex_throws_define 700 AT_JT_initial_action], 701 [AT_JT_yylex_throws], 702 [AT_JT_yylex_action], 703 [], 704 [AT_JT_parse_action])]) 705 AT_CHECK_JAVA_GREP([[ *int yylex ()]AT_JT_yylex_throws *[;]]) 706 AT_CHECK_JAVA_GREP([[ *private int yyaction ([^)]*)]AT_JT_yyaction_throws[ *]]) 707 AT_CHECK_JAVA_GREP([[ *public boolean parse ()]AT_JT_parse_throws[ *]]) 708 ])])]) 709 710 AT_CLEANUP 711 712 713 # --------------------------------------------- # 714 # Java stype, position_class and location_class # 715 # --------------------------------------------- # 716 717 AT_SETUP([Java stype, position_class and location_class]) 718 719 AT_CHECK_JAVA_MINIMAL([[ 720 %define stype "java.awt.Color" 721 %type<java.awt.Color> start; 722 %define api.location.type "MyLoc" 723 %define api.position.type "MyPos" 724 %code { class MyPos {} }]], [[$$ = $<java.awt.Color>1;]], [[MyPos]]) 725 AT_CHECK([[grep 'java.awt.Color' YYParser.java]], [0], [ignore]) 726 AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Position']], [1], [ignore]) 727 AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Location']], [1], [ignore]) 728 729 AT_CHECK_JAVA_MINIMAL_W_LEXER([[ 730 %define stype "java.awt.Color" 731 %type<java.awt.Color> start; 732 %define api.location.type "MyLoc" 733 %define api.position.type "MyPos" 734 %code { class MyPos {} }]], [], [[return EOF;]], [], 735 [[$$ = $<java.awt.Color>1;]], 736 [[java.awt.Color]], [[MyPos]], [[MyLoc]]) 737 AT_CHECK([[grep 'java.awt.Color' YYParser.java]], [0], [ignore]) 738 AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Position']], [1], [ignore]) 739 AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Location']], [1], [ignore]) 740 741 AT_CLEANUP 742 743 744 # ----------------------------------------------- # 745 # Java syntax error handling without error token. # 746 # ----------------------------------------------- # 747 748 AT_SETUP([Java syntax error handling without error token]) 749 750 AT_DATA([[YYParser.y]], [[%language "Java" 751 752 %lex-param { String s } 753 754 %code imports { 755 import java.io.IOException; 756 } 757 758 %code lexer { 759 String Input; 760 int Position; 761 762 public YYLexer (String s) 763 { 764 Input = s; 765 Position = 0; 766 } 767 768 public void yyerror (String s) 769 { 770 System.err.println (s); 771 } 772 773 public Object getLVal () 774 { 775 return null; 776 } 777 778 public int yylex () throws IOException 779 { 780 if (Position >= Input.length ()) 781 return EOF; 782 else 783 return Input.charAt (Position++); 784 } 785 } 786 787 %code { 788 public static void main (String args []) throws IOException 789 { 790 YYParser p = new YYParser (args [0]); 791 p.parse (); 792 } 793 } 794 %% 795 input: 796 'a' 'a' 797 ; 798 ]]) 799 AT_BISON_CHECK([[YYParser.y]]) 800 AT_JAVA_COMPILE([[YYParser.java]]) 801 AT_JAVA_PARSER_CHECK([[YYParser aa]], [[0]], [[]], [[]]) 802 AT_JAVA_PARSER_CHECK([[YYParser ab]], [[0]], [[]], [[syntax error 803 ]]) 804 AT_JAVA_PARSER_CHECK([[YYParser ba]], [[0]], [[]], [[syntax error 805 ]]) 806 807 AT_CLEANUP 808