1 # Java tests for simple calculator. -*- Autotest -*-
3 # Copyright (C) 2007-2015, 2018-2021 Free Software Foundation, Inc.
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.
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.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <https://www.gnu.org/licenses/>.
18 AT_BANNER([[Java Calculator.]])
21 ## ------------------------- ##
22 ## Java invalid directives. ##
23 ## ------------------------- ##
25 AT_SETUP([Java invalid directives])
27 AT_DATA([[YYParser.y]], [
30 %destructor { /* Nothing. */ } exp
35 AT_BISON_CHECK([[-fcaret YYParser.y]], [1], [],
36 [[YYParser.y: error: %defines does not make sense in Java
37 YYParser.y:4.13-30: error: %destructor does not make sense in Java
38 4 | %destructor { /* Nothing. */ } exp
45 ## ------------------------- ##
46 ## Helping Autotest macros. ##
47 ## ------------------------- ##
50 # AT_JAVA_POSITION_DEFINE_OLD
51 # -----------------------
52 m4_define([AT_JAVA_POSITION_DEFINE_OLD],
63 public Position (int l, int t)
69 public boolean equals (Position l)
71 return l.line == line && l.token == token;
74 public String toString ()
76 return Integer.toString (line) + "." + Integer.toString (token);
94 ## ----------------- ##
95 ## Java Parameters. ##
96 ## ----------------- ##
98 AT_BANNER([Java Parameters.])
101 # AT_CHECK_JAVA_MINIMAL([DIRECTIVES], [PARSER_ACTION], [POSITION_CLASS])
102 # ----------------------------------------------------------------------
103 # Check that a minimal parser with DIRECTIVES compiles in Java.
104 # Put the Java code in YYParser.java.
105 m4_define([AT_CHECK_JAVA_MINIMAL],
107 AT_DATA([[YYParser.y]], [
111 %define parse.error verbose
118 class m4_default([$3], [Position]) {}
120 AT_BISON_CHECK([[-Wno-deprecated YYParser.y]])
121 AT_CHECK([[grep '[mb]4_' YYParser.y]], [1], [ignore])
122 AT_JAVA_COMPILE([[YYParser.java]])
126 # AT_CHECK_JAVA_MINIMAL_W_LEXER([1:DIRECTIVES], [2:LEX_THROWS],
127 # [3:YYLEX_ACTION], [4:LEXER_BODY], [5:PARSER_ACTION], [6:VALUE_TYPE],
128 # [7:POSITION_TYPE], [8:LOCATION_TYPE])
129 # ---------------------------------------------------------------------
130 # Check that a minimal parser with DIRECTIVES and a "%code lexer".
131 # YYLEX is the body of yylex () which throws LEX_THROW.
133 m4_define([AT_CHECK_JAVA_MINIMAL_W_LEXER],
134 [AT_CHECK_JAVA_MINIMAL([$1
138 m4_default([$6], [Object]) yylval;
139 public m4_default([$6], [Object]) getLVal() { return yylval; }
141 public m4_default([$7], [Position]) getStartPos() { return null; }
142 public m4_default([$7], [Position]) getEndPos() { return null; }
144 public void yyerror (m4_default([$8], [Location]) loc, String s)
146 System.err.println (loc + ": " + s);
158 # AT_CHECK_JAVA_GREP([LINE], [COUNT=1])
159 # -------------------------------------
160 # Check that YYParser.java contains exactly COUNT lines matching ^LINE$
162 m4_define([AT_CHECK_JAVA_GREP],
163 [AT_CHECK([grep -c '^$1$' YYParser.java], [ignore], [m4_default([$2], [1])
167 ## ------------------------------------- ##
168 ## Java parser class and package names. ##
169 ## ------------------------------------- ##
171 AT_SETUP([Java parser class and package names])
173 AT_CHECK_JAVA_MINIMAL([])
174 AT_CHECK_JAVA_GREP([[class YYParser]])
176 AT_CHECK_JAVA_MINIMAL([[%name-prefix "Prefix"]])
177 AT_CHECK_JAVA_GREP([[class PrefixParser]])
179 AT_CHECK_JAVA_MINIMAL([[%define api.prefix {Prefix}]])
180 AT_CHECK_JAVA_GREP([[class PrefixParser]])
182 AT_CHECK_JAVA_MINIMAL([[%define api.token.prefix {TOK_}]])
183 AT_CHECK_JAVA_GREP([[.*TOK_END.*]])
185 AT_CHECK_JAVA_MINIMAL([[%define api.parser.class {ParserClassName}]])
186 AT_CHECK_JAVA_GREP([[class ParserClassName]])
188 AT_CHECK_JAVA_MINIMAL([[%define api.package {user_java_package}]])
189 AT_CHECK_JAVA_GREP([[package user_java_package;]])
191 # Backward compatibility.
192 AT_CHECK_JAVA_MINIMAL([[%define package {user_java_package}]])
193 AT_CHECK_JAVA_GREP([[package user_java_package;]])
198 ## ----------------------------- ##
199 ## Java parser class modifiers. ##
200 ## ----------------------------- ##
202 AT_SETUP([Java parser class modifiers])
204 AT_CHECK_JAVA_MINIMAL([[%define abstract]])
205 AT_CHECK_JAVA_GREP([[abstract class YYParser]])
207 AT_CHECK_JAVA_MINIMAL([[%define final]])
208 AT_CHECK_JAVA_GREP([[final class YYParser]])
210 AT_CHECK_JAVA_MINIMAL([[%define strictfp]])
211 AT_CHECK_JAVA_GREP([[strictfp class YYParser]])
213 AT_CHECK_JAVA_MINIMAL([[
216 AT_CHECK_JAVA_GREP([[abstract strictfp class YYParser]])
218 AT_CHECK_JAVA_MINIMAL([[
221 AT_CHECK_JAVA_GREP([[final strictfp class YYParser]])
223 AT_CHECK_JAVA_MINIMAL([[%define public]])
224 AT_CHECK_JAVA_GREP([[public class YYParser]])
226 AT_CHECK_JAVA_MINIMAL([[
229 AT_CHECK_JAVA_GREP([[public abstract class YYParser]])
231 AT_CHECK_JAVA_MINIMAL([[
234 AT_CHECK_JAVA_GREP([[public final class YYParser]])
236 AT_CHECK_JAVA_MINIMAL([[
239 AT_CHECK_JAVA_GREP([[public strictfp class YYParser]])
241 AT_CHECK_JAVA_MINIMAL([[
245 AT_CHECK_JAVA_GREP([[public abstract strictfp class YYParser]])
247 AT_CHECK_JAVA_MINIMAL([[
251 AT_CHECK_JAVA_GREP([[public final strictfp class YYParser]])
253 AT_CHECK_JAVA_MINIMAL([[
254 %define api.parser.public
255 %define api.parser.final
256 %define api.parser.strictfp]])
257 AT_CHECK_JAVA_GREP([[public final strictfp class YYParser]])
259 # FIXME: Can't do a Java compile because javacomp.sh is configured for 1.3
260 AT_CHECK_JAVA_MINIMAL([[
261 %define annotations {/*@Deprecated @SuppressWarnings("unchecked") @SuppressWarnings({"unchecked", "deprecation"}) @SuppressWarnings(value={"unchecked", "deprecation"})*/}
263 AT_CHECK_JAVA_GREP([[/\*@Deprecated @SuppressWarnings("unchecked") @SuppressWarnings({"unchecked", "deprecation"}) @SuppressWarnings(value={"unchecked", "deprecation"})\*/ public class YYParser]])
268 ## ---------------------------------------- ##
269 ## Java parser class extends and implements ##
270 ## ---------------------------------------- ##
272 AT_SETUP([Java parser class extends and implements])
274 AT_CHECK_JAVA_MINIMAL([[%define extends {Thread}]])
275 AT_CHECK_JAVA_GREP([[class YYParser extends Thread]])
277 AT_CHECK_JAVA_MINIMAL([[%define implements {Cloneable}]])
278 AT_CHECK_JAVA_GREP([[class YYParser implements Cloneable]])
280 AT_CHECK_JAVA_MINIMAL([[
281 %define extends {Thread}
282 %define implements {Cloneable}]])
283 AT_CHECK_JAVA_GREP([[class YYParser extends Thread implements Cloneable]])
288 ## -------------------------------- ##
289 ## Java %parse-param and %lex-param ##
290 ## -------------------------------- ##
292 AT_SETUP([Java %parse-param and %lex-param])
294 AT_CHECK_JAVA_MINIMAL([])
295 AT_CHECK_JAVA_GREP([[ *public YYParser (Lexer yylexer) *]])
297 AT_CHECK_JAVA_MINIMAL([[%parse-param {int parse_param1}]])
298 AT_CHECK_JAVA_GREP([[ *protected final int parse_param1;]])
299 AT_CHECK_JAVA_GREP([[ *public YYParser (Lexer yylexer, *int parse_param1) *]])
300 AT_CHECK_JAVA_GREP([[ *this.parse_param1 = parse_param1;]])
302 AT_CHECK_JAVA_MINIMAL([[
303 %parse-param {int parse_param1}
304 %parse-param {long parse_param2}]])
305 AT_CHECK_JAVA_GREP([[ *protected final int parse_param1;]])
306 AT_CHECK_JAVA_GREP([[ *protected final long parse_param2;]])
307 AT_CHECK_JAVA_GREP([[ *public YYParser (Lexer yylexer, *int parse_param1, *long parse_param2) *]])
308 AT_CHECK_JAVA_GREP([[ *this.parse_param1 = parse_param1;]])
309 AT_CHECK_JAVA_GREP([[ *this.parse_param2 = parse_param2;]])
311 AT_CHECK_JAVA_MINIMAL_W_LEXER([], [], [[return EOF;]])
312 AT_CHECK_JAVA_GREP([[ *public YYParser () *]])
313 AT_CHECK_JAVA_GREP([[ *protected YYParser (Lexer yylexer) *]])
315 AT_CHECK_JAVA_MINIMAL_W_LEXER([[%parse-param {int parse_param1}]],
317 AT_CHECK_JAVA_GREP([[ *protected final int parse_param1;]])
318 AT_CHECK_JAVA_GREP([[ *public YYParser (int parse_param1) *]])
319 AT_CHECK_JAVA_GREP([[ *protected YYParser (Lexer yylexer, *int parse_param1) *]])
320 AT_CHECK_JAVA_GREP([[ *this.parse_param1 = parse_param1;]], [2])
322 AT_CHECK_JAVA_MINIMAL_W_LEXER([[
323 %parse-param {int parse_param1}
324 %parse-param {long parse_param2}]],
326 AT_CHECK_JAVA_GREP([[ *protected final int parse_param1;]])
327 AT_CHECK_JAVA_GREP([[ *protected final long parse_param2;]])
328 AT_CHECK_JAVA_GREP([[ *public YYParser (int parse_param1, *long parse_param2) *]])
329 AT_CHECK_JAVA_GREP([[ *protected YYParser (Lexer yylexer, *int parse_param1, *long parse_param2) *]])
330 AT_CHECK_JAVA_GREP([[ *this.parse_param1 = parse_param1;]], [2])
331 AT_CHECK_JAVA_GREP([[ *this.parse_param2 = parse_param2;]], [2])
333 AT_CHECK_JAVA_MINIMAL_W_LEXER([[%lex-param {char lex_param1}]],
334 [], [[return EOF;]], [[YYLexer (char lex_param1) {}]])
335 AT_CHECK_JAVA_GREP([[ *public YYParser (char lex_param1) *]])
336 AT_CHECK_JAVA_GREP([[.* = new YYLexer *(lex_param1);]])
338 AT_CHECK_JAVA_MINIMAL_W_LEXER([[
339 %lex-param {char lex_param1}
340 %lex-param {short lex_param2}]],
341 [], [[return EOF;]], [[YYLexer (char lex_param1, short lex_param2) {}]])
342 AT_CHECK_JAVA_GREP([[ *public YYParser (char lex_param1, *short lex_param2) *]])
343 AT_CHECK_JAVA_GREP([[.* = new YYLexer *(lex_param1, *lex_param2);]])
345 AT_CHECK_JAVA_MINIMAL_W_LEXER([[
346 %parse-param {int parse_param1}
347 %parse-param {long parse_param2}
348 %lex-param {char lex_param1}
349 %lex-param {short lex_param2}]],
350 [], [[return EOF;]], [[YYLexer (char lex_param1, short lex_param2) {}]])
351 AT_CHECK_JAVA_GREP([[ *protected final int parse_param1;]])
352 AT_CHECK_JAVA_GREP([[ *protected final long parse_param2;]])
353 AT_CHECK_JAVA_GREP([[ *public YYParser (char lex_param1, *short lex_param2, *int parse_param1, *long parse_param2) *]])
354 AT_CHECK_JAVA_GREP([[.* = new YYLexer *(lex_param1, *lex_param2);]])
355 AT_CHECK_JAVA_GREP([[ *protected YYParser (Lexer yylexer, *int parse_param1, *long parse_param2) *]])
356 AT_CHECK_JAVA_GREP([[ *this.parse_param1 = parse_param1;]], [2])
357 AT_CHECK_JAVA_GREP([[ *this.parse_param2 = parse_param2;]], [2])
362 ## --------------------------- ##
363 ## Java throw specifications. ##
364 ## --------------------------- ##
366 AT_SETUP([Java throws specifications])
368 # %define throws - 0 1 2
369 # %define lex-throws - 0 1 2
372 m4_define([AT_JT_lex_throws_define], [m4_case(AT_JT_lex_throws,
374 0, [[%define lex_throws {}]],
375 1, [[%define lex_throws {InterruptedException}]],
376 2, [[%define lex_throws {InterruptedException, IllegalAccessException}]])])
378 m4_define([AT_JT_yylex_throws], [m4_case(AT_JT_lex_throws,
379 -1, [[ throws java.io.IOException]],
381 1, [[ throws InterruptedException]],
382 2, [[ throws InterruptedException, IllegalAccessException]])])
384 m4_define([AT_JT_yylex_action], [m4_case(AT_JT_lex_throws,
385 -1, [[throw new java.io.IOException();]],
387 1, [[throw new InterruptedException();]],
388 2, [[throw new IllegalAccessException();]])])
391 m4_define([AT_JT_throws_define], [m4_case(AT_JT_throws,
393 0, [[%define throws {}]],
394 1, [[%define throws {ClassNotFoundException}]],
395 2, [[%define throws {ClassNotFoundException, InstantiationException}]])])
397 m4_define([AT_JT_yyaction_throws], [m4_case(AT_JT_throws,
400 1, [[ throws ClassNotFoundException]],
401 2, [[ throws ClassNotFoundException, InstantiationException]])])
403 m4_define([AT_JT_parse_throws_2], [m4_case(AT_JT_throws,
406 1, [[, ClassNotFoundException]],
407 2, [[, ClassNotFoundException, InstantiationException]])])
409 m4_define([AT_JT_parse_throws],
410 [m4_if(m4_quote(AT_JT_yylex_throws), [],
411 [AT_JT_yyaction_throws],
412 [AT_JT_yylex_throws[]AT_JT_parse_throws_2])])
414 m4_define([AT_JT_initial_action], [m4_case(AT_JT_throws,
417 1, [[%initial-action {if (true) throw new ClassNotFoundException();}]],
418 2, [[%initial-action {if (true) throw new InstantiationException();}]])])
420 m4_define([AT_JT_parse_action], [m4_case(AT_JT_throws,
423 1, [[throw new ClassNotFoundException();]],
424 2, [[throw new ClassNotFoundException();]])])
426 m4_for([AT_JT_lexer], 0, 1, 1,
427 [m4_for([AT_JT_lex_throws], -1, 2, 1,
428 [m4_for([AT_JT_throws], -1, 2, 1,
429 [m4_if(AT_JT_lexer, 0,
430 [AT_CHECK_JAVA_MINIMAL([
432 AT_JT_lex_throws_define
433 AT_JT_initial_action],
434 [AT_JT_parse_action])],
435 [AT_CHECK_JAVA_MINIMAL_W_LEXER([
437 AT_JT_lex_throws_define
438 AT_JT_initial_action],
439 [AT_JT_yylex_throws],
440 [AT_JT_yylex_action],
442 [AT_JT_parse_action])])
443 AT_CHECK_JAVA_GREP([[ *int yylex()]AT_JT_yylex_throws *[;]])
444 AT_CHECK_JAVA_GREP([[ *private int yyaction([^)]*)]AT_JT_yyaction_throws[ *]])
445 AT_CHECK_JAVA_GREP([[ *public boolean parse()]AT_JT_parse_throws[ *]])
451 ## --------------------------------------- ##
452 ## Java constructor init and init_throws. ##
453 ## --------------------------------------- ##
455 AT_SETUP([Java constructor init and init_throws])
457 m4_pushdef([AT_Witness],
458 [super("Test Thread"); if (true) throw new InterruptedException();])
460 AT_CHECK_JAVA_MINIMAL([[
461 %define extends {Thread}
462 %code init { ]AT_Witness[ }
463 %define init_throws {InterruptedException}
464 %lex-param {int lex_param}]])
465 AT_CHECK([[grep ']AT_Witness[' YYParser.java]], 0, [ignore])
467 AT_CHECK_JAVA_MINIMAL_W_LEXER([[
468 %define extends {Thread}
469 %code init { ]AT_Witness[ }
470 %define init_throws {InterruptedException}]], [], [[return EOF;]])
471 AT_CHECK([[grep ']AT_Witness[' YYParser.java]], 0, [ignore])
473 m4_popdef([AT_Witness])
478 ## ------------------------------------------ ##
479 ## Java value, position, and location types. ##
480 ## ------------------------------------------ ##
482 AT_SETUP([Java value, position, and location types])
484 AT_CHECK_JAVA_MINIMAL([[
485 %define api.value.type {java.awt.Color}
486 %type<java.awt.Color> start;
487 %define api.location.type {MyLoc}
488 %define api.position.type {MyPos}
489 %code { class MyPos {} }]], [[$$ = $<java.awt.Color>1;]], [[MyPos]])
490 AT_CHECK([[grep 'java.awt.Color' YYParser.java]], [0], [ignore])
491 AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep -w 'Position']], [1], [ignore])
492 AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep -w 'Location']], [1], [ignore])
494 AT_CHECK_JAVA_MINIMAL_W_LEXER([[
495 %define api.value.type {java.awt.Color}
496 %type<java.awt.Color> start;
497 %define api.location.type {MyLoc}
498 %define api.position.type {MyPos}
499 %code { class MyPos {} }]], [], [[return EOF;]], [],
500 [[$$ = $<java.awt.Color>1;]],
501 [[java.awt.Color]], [[MyPos]], [[MyLoc]])
502 AT_CHECK([[grep 'java.awt.Color' YYParser.java]], [0], [ignore])
503 AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep -w 'Position']], [1], [ignore])
504 AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep -w 'Location']], [1], [ignore])
509 ## ------------------------------------------------ ##
510 ## Java syntax error handling without error token. ##
511 ## ------------------------------------------------ ##
513 AT_SETUP([Java syntax error handling without error token])
515 AT_DATA([[YYParser.y]], [[%language "Java"
517 %lex-param { String s }
520 import java.io.IOException;
527 public YYLexer (String s)
533 public void yyerror (String s)
535 System.err.println (s);
538 public Object getLVal ()
543 public int yylex () throws IOException
545 if (Position >= Input.length ())
548 return Input.charAt (Position++);
553 public static void main (String args []) throws IOException
555 YYParser p = new YYParser (args [0]);
564 AT_BISON_CHECK([[YYParser.y]])
565 AT_JAVA_COMPILE([[YYParser.java]])
566 AT_JAVA_PARSER_CHECK([[YYParser aa]], [[0]], [[]], [[]])
567 AT_JAVA_PARSER_CHECK([[YYParser ab]], [[0]], [[]], [[syntax error
569 AT_JAVA_PARSER_CHECK([[YYParser ba]], [[0]], [[]], [[syntax error