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 18AT_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. 32m4_define([_AT_DATA_JAVA_CALC_Y], 33[m4_if([$1$2$3], $[1]$[2]$[3], [], 34 [m4_fatal([$0: Invalid arguments: $@])])dnl 35AT_BISON_OPTION_PUSHDEFS([%language "Java" $4]) 36AT_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%% 65input: 66 line 67| input line 68; 69 70line: 71 '\n' 72| exp '\n' 73| error '\n' 74; 75 76exp: 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%% 102class 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 116AT_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[ 165class 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]]) 203AT_BISON_OPTION_POPDEFS 204])# _AT_DATA_JAVA_CALC_Y 205 206 207# AT_DATA_CALC_Y([BISON-OPTIONS]) 208# ------------------------------- 209# Produce `calc.y'. 210m4_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. 225m4_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]]) 231AT_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. 236AT_DATA([[expout]], 237[$3 238]) 239# 2. If locations are not used, remove them. 240AT_YYERROR_SEES_LOC_IF([], 241[[sed 's/^[-0-9.]*: //' expout >at-expout 242mv at-expout expout]]) 243# 3. If error-verbose is not used, strip the`, unexpected....' part. 244m4_bmatch([$1], [%error-verbose], [], 245[[sed 's/syntax error, .*$/syntax error/' expout >at-expout 246mv at-expout expout]]) 247# 4. Check 248AT_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. 255m4_define([_AT_CHECK_JAVA_CALC], 256[# We use integers to avoid dependencies upon the precision of doubles. 257AT_SETUP([Calculator $1]) 258 259AT_BISON_OPTION_PUSHDEFS([$1]) 260 261AT_DATA_JAVA_CALC_Y([$1 262%code { 263$2 264}]) 265 266AT_BISON_CHECK([-o Calc.java Calc.y]) 267AT_JAVA_COMPILE([Calc.java]) 268 269# Test the priorities. 270AT_DATA([[input]], 271[[1 + 2 * 3 = 7 2721 + 2 * -3 = -5 273 274-1^2 = -1 275(-1)^2 = 1 276 277---1 = -1 278 2791 - 2 - 3 = -4 2801 - (2 - 3) = 2 281 2822^2^3 = 256 283(2^2)^3 = 64 284]]) 285AT_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 '!' 3231.11: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 3241.14: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 3251.24: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 3261.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 3321.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 '!' 3351.8: syntax error, unexpected number 3361.1-1.11: calc: error: 2222 != 1]) 337AT_BISON_OPTION_POPDEFS 338 339AT_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. 348m4_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 360AT_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 369AT_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 382AT_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. 389m4_define([AT_CHECK_JAVA_MINIMAL], 390[ 391AT_DATA([[YYParser.y]], [ 392%language "Java" 393%locations 394%debug 395%error-verbose 396%token-table 397$1 398%% 399start: "end" {$2}; 400%% 401class m4_default([$3], [Position]) {} 402]) 403AT_BISON_CHECK([[YYParser.y]]) 404AT_CHECK([[grep '[mb]4_' YYParser.y]], [1], [ignore]) 405AT_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. 416m4_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. 445m4_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 455AT_SETUP([Java parser class and package names]) 456 457AT_CHECK_JAVA_MINIMAL([]) 458AT_CHECK_JAVA_GREP([[class YYParser]]) 459 460AT_CHECK_JAVA_MINIMAL([[%name-prefix "Prefix"]]) 461AT_CHECK_JAVA_GREP([[class PrefixParser]]) 462 463AT_CHECK_JAVA_MINIMAL([[%define parser_class_name "ParserClassName"]]) 464AT_CHECK_JAVA_GREP([[class ParserClassName]]) 465 466AT_CHECK_JAVA_MINIMAL([[%define package "user_java_package"]]) 467AT_CHECK_JAVA_GREP([[package user_java_package;]]) 468 469AT_CLEANUP 470 471 472# --------------------------- # 473# Java parser class modifiers # 474# --------------------------- # 475 476AT_SETUP([Java parser class modifiers]) 477 478AT_CHECK_JAVA_MINIMAL([[%define abstract]]) 479AT_CHECK_JAVA_GREP([[abstract class YYParser]]) 480 481AT_CHECK_JAVA_MINIMAL([[%define final]]) 482AT_CHECK_JAVA_GREP([[final class YYParser]]) 483 484AT_CHECK_JAVA_MINIMAL([[%define strictfp]]) 485AT_CHECK_JAVA_GREP([[strictfp class YYParser]]) 486 487AT_CHECK_JAVA_MINIMAL([[ 488%define abstract 489%define strictfp]]) 490AT_CHECK_JAVA_GREP([[abstract strictfp class YYParser]]) 491 492AT_CHECK_JAVA_MINIMAL([[ 493%define final 494%define strictfp]]) 495AT_CHECK_JAVA_GREP([[final strictfp class YYParser]]) 496 497AT_CHECK_JAVA_MINIMAL([[%define public]]) 498AT_CHECK_JAVA_GREP([[public class YYParser]]) 499 500AT_CHECK_JAVA_MINIMAL([[ 501%define public 502%define abstract]]) 503AT_CHECK_JAVA_GREP([[public abstract class YYParser]]) 504 505AT_CHECK_JAVA_MINIMAL([[ 506%define public 507%define final]]) 508AT_CHECK_JAVA_GREP([[public final class YYParser]]) 509 510AT_CHECK_JAVA_MINIMAL([[ 511%define public 512%define strictfp]]) 513AT_CHECK_JAVA_GREP([[public strictfp class YYParser]]) 514 515AT_CHECK_JAVA_MINIMAL([[ 516%define public 517%define abstract 518%define strictfp]]) 519AT_CHECK_JAVA_GREP([[public abstract strictfp class YYParser]]) 520 521AT_CHECK_JAVA_MINIMAL([[ 522%define public 523%define final 524%define strictfp]]) 525AT_CHECK_JAVA_GREP([[public final strictfp class YYParser]]) 526 527AT_CLEANUP 528 529 530# ---------------------------------------- # 531# Java parser class extends and implements # 532# ---------------------------------------- # 533 534AT_SETUP([Java parser class extends and implements]) 535 536AT_CHECK_JAVA_MINIMAL([[%define extends "Thread"]]) 537AT_CHECK_JAVA_GREP([[class YYParser extends Thread]]) 538 539AT_CHECK_JAVA_MINIMAL([[%define implements "Cloneable"]]) 540AT_CHECK_JAVA_GREP([[class YYParser implements Cloneable]]) 541 542AT_CHECK_JAVA_MINIMAL([[ 543%define extends "Thread" 544%define implements "Cloneable"]]) 545AT_CHECK_JAVA_GREP([[class YYParser extends Thread implements Cloneable]]) 546 547AT_CLEANUP 548 549 550# -------------------------------- # 551# Java %parse-param and %lex-param # 552# -------------------------------- # 553 554AT_SETUP([Java %parse-param and %lex-param]) 555 556AT_CHECK_JAVA_MINIMAL([]) 557AT_CHECK_JAVA_GREP([[ *public YYParser (Lexer yylexer) {]]) 558 559AT_CHECK_JAVA_MINIMAL([[%parse-param {int parse_param1}]]) 560AT_CHECK_JAVA_GREP([[ *protected final int parse_param1;]]) 561AT_CHECK_JAVA_GREP([[ *public YYParser (Lexer yylexer, *int parse_param1) {]]) 562AT_CHECK_JAVA_GREP([[[ ]*this.parse_param1 = parse_param1;]]) 563 564AT_CHECK_JAVA_MINIMAL([[ 565%parse-param {int parse_param1} 566%parse-param {long parse_param2}]]) 567AT_CHECK_JAVA_GREP([[ *protected final int parse_param1;]]) 568AT_CHECK_JAVA_GREP([[ *protected final long parse_param2;]]) 569AT_CHECK_JAVA_GREP([[ *public YYParser (Lexer yylexer, *int parse_param1, *long parse_param2) {]]) 570AT_CHECK_JAVA_GREP([[[ ]*this.parse_param1 = parse_param1;]]) 571AT_CHECK_JAVA_GREP([[[ ]*this.parse_param2 = parse_param2;]]) 572 573AT_CHECK_JAVA_MINIMAL_W_LEXER([], [], [[return EOF;]]) 574AT_CHECK_JAVA_GREP([[ *public YYParser () {]]) 575AT_CHECK_JAVA_GREP([[ *protected YYParser (Lexer yylexer) {]]) 576 577AT_CHECK_JAVA_MINIMAL_W_LEXER([[%parse-param {int parse_param1}]], 578 [], [[return EOF;]]) 579AT_CHECK_JAVA_GREP([[ *protected final int parse_param1;]]) 580AT_CHECK_JAVA_GREP([[ *public YYParser (int parse_param1) {]]) 581AT_CHECK_JAVA_GREP([[ *protected YYParser (Lexer yylexer, *int parse_param1) {]]) 582AT_CHECK_JAVA_GREP([[[ ]*this.parse_param1 = parse_param1;]], [2]) 583 584AT_CHECK_JAVA_MINIMAL_W_LEXER([[ 585%parse-param {int parse_param1} 586%parse-param {long parse_param2}]], 587 [], [[return EOF;]]) 588AT_CHECK_JAVA_GREP([[ *protected final int parse_param1;]]) 589AT_CHECK_JAVA_GREP([[ *protected final long parse_param2;]]) 590AT_CHECK_JAVA_GREP([[ *public YYParser (int parse_param1, *long parse_param2) {]]) 591AT_CHECK_JAVA_GREP([[ *protected YYParser (Lexer yylexer, *int parse_param1, *long parse_param2) {]]) 592AT_CHECK_JAVA_GREP([[[ ]*this.parse_param1 = parse_param1;]], [2]) 593AT_CHECK_JAVA_GREP([[[ ]*this.parse_param2 = parse_param2;]], [2]) 594 595AT_CHECK_JAVA_MINIMAL_W_LEXER([[%lex-param {char lex_param1}]], 596 [], [[return EOF;]], [[YYLexer (char lex_param1) {}]]) 597AT_CHECK_JAVA_GREP([[ *public YYParser (char lex_param1) {]]) 598AT_CHECK_JAVA_GREP([[.* = new YYLexer *(lex_param1);]]) 599 600AT_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) {}]]) 604AT_CHECK_JAVA_GREP([[ *public YYParser (char lex_param1, *short lex_param2) {]]) 605AT_CHECK_JAVA_GREP([[.* = new YYLexer *(lex_param1, *lex_param2);]]) 606 607AT_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) {}]]) 613AT_CHECK_JAVA_GREP([[ *protected final int parse_param1;]]) 614AT_CHECK_JAVA_GREP([[ *protected final long parse_param2;]]) 615AT_CHECK_JAVA_GREP([[ *public YYParser (char lex_param1, *short lex_param2, *int parse_param1, *long parse_param2) {]]) 616AT_CHECK_JAVA_GREP([[.* = new YYLexer *(lex_param1, *lex_param2);]]) 617AT_CHECK_JAVA_GREP([[ *protected YYParser (Lexer yylexer, *int parse_param1, *long parse_param2) {]]) 618AT_CHECK_JAVA_GREP([[[ ]*this.parse_param1 = parse_param1;]], [2]) 619AT_CHECK_JAVA_GREP([[[ ]*this.parse_param2 = parse_param2;]], [2]) 620 621AT_CLEANUP 622 623 624# ------------------------- # 625# Java throw specifications # 626# ------------------------- # 627 628AT_SETUP([Java throws specifications]) 629 630# %define throws - 0 1 2 631# %define lex-throws - 0 1 2 632# %code lexer 0 1 633 634m4_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 640m4_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 646m4_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 653m4_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 659m4_define([AT_JT_yyaction_throws], [m4_case(AT_JT_throws, 660 -1, [], 661 0, [], 662 1, [[ throws ClassNotFoundException]], 663 2, [[ throws ClassNotFoundException, InstantiationException]])]) 664 665m4_define([AT_JT_parse_throws_2], [m4_case(AT_JT_throws, 666 -1, [], 667 0, [], 668 1, [[, ClassNotFoundException]], 669 2, [[, ClassNotFoundException, InstantiationException]])]) 670 671m4_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 676m4_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 682m4_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 688m4_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([ 693AT_JT_throws_define 694AT_JT_lex_throws_define 695AT_JT_initial_action], 696[AT_JT_parse_action])], 697 [AT_CHECK_JAVA_MINIMAL_W_LEXER([ 698AT_JT_throws_define 699AT_JT_lex_throws_define 700AT_JT_initial_action], 701[AT_JT_yylex_throws], 702[AT_JT_yylex_action], 703[], 704[AT_JT_parse_action])]) 705AT_CHECK_JAVA_GREP([[ *int yylex ()]AT_JT_yylex_throws *[;]]) 706AT_CHECK_JAVA_GREP([[ *private int yyaction ([^)]*)]AT_JT_yyaction_throws[ *]]) 707AT_CHECK_JAVA_GREP([[ *public boolean parse ()]AT_JT_parse_throws[ *]]) 708])])]) 709 710AT_CLEANUP 711 712 713# --------------------------------------------- # 714# Java stype, position_class and location_class # 715# --------------------------------------------- # 716 717AT_SETUP([Java stype, position_class and location_class]) 718 719AT_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]]) 725AT_CHECK([[grep 'java.awt.Color' YYParser.java]], [0], [ignore]) 726AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Position']], [1], [ignore]) 727AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Location']], [1], [ignore]) 728 729AT_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]]) 737AT_CHECK([[grep 'java.awt.Color' YYParser.java]], [0], [ignore]) 738AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Position']], [1], [ignore]) 739AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Location']], [1], [ignore]) 740 741AT_CLEANUP 742 743 744# ----------------------------------------------- # 745# Java syntax error handling without error token. # 746# ----------------------------------------------- # 747 748AT_SETUP([Java syntax error handling without error token]) 749 750AT_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%% 795input: 796 'a' 'a' 797; 798]]) 799AT_BISON_CHECK([[YYParser.y]]) 800AT_JAVA_COMPILE([[YYParser.java]]) 801AT_JAVA_PARSER_CHECK([[YYParser aa]], [[0]], [[]], [[]]) 802AT_JAVA_PARSER_CHECK([[YYParser ab]], [[0]], [[]], [[syntax error 803]]) 804AT_JAVA_PARSER_CHECK([[YYParser ba]], [[0]], [[]], [[syntax error 805]]) 806 807AT_CLEANUP 808