Scanner.java revision 51b1b6997fd3f980076b8081f7f1165ccc2a4008
1/*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.util;
27
28import java.nio.file.Path;
29import java.nio.file.Files;
30import java.util.regex.*;
31import java.io.*;
32import java.math.*;
33import java.nio.*;
34import java.nio.channels.*;
35import java.nio.charset.*;
36import java.text.*;
37import java.util.Locale;
38
39import sun.misc.LRUCache;
40
41/**
42 * A simple text scanner which can parse primitive types and strings using
43 * regular expressions.
44 *
45 * <p>A <code>Scanner</code> breaks its input into tokens using a
46 * delimiter pattern, which by default matches whitespace. The resulting
47 * tokens may then be converted into values of different types using the
48 * various <tt>next</tt> methods.
49 *
50 * <p>For example, this code allows a user to read a number from
51 * <tt>System.in</tt>:
52 * <blockquote><pre>
53 *     Scanner sc = new Scanner(System.in);
54 *     int i = sc.nextInt();
55 * </pre></blockquote>
56 *
57 * <p>As another example, this code allows <code>long</code> types to be
58 * assigned from entries in a file <code>myNumbers</code>:
59 * <blockquote><pre>
60 *      Scanner sc = new Scanner(new File("myNumbers"));
61 *      while (sc.hasNextLong()) {
62 *          long aLong = sc.nextLong();
63 *      }</pre></blockquote>
64 *
65 * <p>The scanner can also use delimiters other than whitespace. This
66 * example reads several items in from a string:
67 *<blockquote><pre>
68 *     String input = "1 fish 2 fish red fish blue fish";
69 *     Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
70 *     System.out.println(s.nextInt());
71 *     System.out.println(s.nextInt());
72 *     System.out.println(s.next());
73 *     System.out.println(s.next());
74 *     s.close(); </pre></blockquote>
75 * <p>
76 * prints the following output:
77 * <blockquote><pre>
78 *     1
79 *     2
80 *     red
81 *     blue </pre></blockquote>
82 *
83 * <p>The same output can be generated with this code, which uses a regular
84 * expression to parse all four tokens at once:
85 *<blockquote><pre>
86 *     String input = "1 fish 2 fish red fish blue fish";
87 *     Scanner s = new Scanner(input);
88 *     s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
89 *     MatchResult result = s.match();
90 *     for (int i=1; i<=result.groupCount(); i++)
91 *         System.out.println(result.group(i));
92 *     s.close(); </pre></blockquote>
93 *
94 * <p>The <a name="default-delimiter">default whitespace delimiter</a> used
95 * by a scanner is as recognized by {@link java.lang.Character}.{@link
96 * java.lang.Character#isWhitespace(char) isWhitespace}. The {@link #reset}
97 * method will reset the value of the scanner's delimiter to the default
98 * whitespace delimiter regardless of whether it was previously changed.
99 *
100 * <p>A scanning operation may block waiting for input.
101 *
102 * <p>The {@link #next} and {@link #hasNext} methods and their
103 * primitive-type companion methods (such as {@link #nextInt} and
104 * {@link #hasNextInt}) first skip any input that matches the delimiter
105 * pattern, and then attempt to return the next token. Both <tt>hasNext</tt>
106 * and <tt>next</tt> methods may block waiting for further input.  Whether a
107 * <tt>hasNext</tt> method blocks has no connection to whether or not its
108 * associated <tt>next</tt> method will block.
109 *
110 * <p> The {@link #findInLine}, {@link #findWithinHorizon}, and {@link #skip}
111 * methods operate independently of the delimiter pattern. These methods will
112 * attempt to match the specified pattern with no regard to delimiters in the
113 * input and thus can be used in special circumstances where delimiters are
114 * not relevant. These methods may block waiting for more input.
115 *
116 * <p>When a scanner throws an {@link InputMismatchException}, the scanner
117 * will not pass the token that caused the exception, so that it may be
118 * retrieved or skipped via some other method.
119 *
120 * <p>Depending upon the type of delimiting pattern, empty tokens may be
121 * returned. For example, the pattern <tt>"\\s+"</tt> will return no empty
122 * tokens since it matches multiple instances of the delimiter. The delimiting
123 * pattern <tt>"\\s"</tt> could return empty tokens since it only passes one
124 * space at a time.
125 *
126 * <p> A scanner can read text from any object which implements the {@link
127 * java.lang.Readable} interface.  If an invocation of the underlying
128 * readable's {@link java.lang.Readable#read} method throws an {@link
129 * java.io.IOException} then the scanner assumes that the end of the input
130 * has been reached.  The most recent <tt>IOException</tt> thrown by the
131 * underlying readable can be retrieved via the {@link #ioException} method.
132 *
133 * <p>When a <code>Scanner</code> is closed, it will close its input source
134 * if the source implements the {@link java.io.Closeable} interface.
135 *
136 * <p>A <code>Scanner</code> is not safe for multithreaded use without
137 * external synchronization.
138 *
139 * <p>Unless otherwise mentioned, passing a <code>null</code> parameter into
140 * any method of a <code>Scanner</code> will cause a
141 * <code>NullPointerException</code> to be thrown.
142 *
143 * <p>A scanner will default to interpreting numbers as decimal unless a
144 * different radix has been set by using the {@link #useRadix} method. The
145 * {@link #reset} method will reset the value of the scanner's radix to
146 * <code>10</code> regardless of whether it was previously changed.
147 *
148 * <a name="localized-numbers">
149 * <h4> Localized numbers </h4>
150 *
151 * <p> An instance of this class is capable of scanning numbers in the standard
152 * formats as well as in the formats of the scanner's locale. A scanner's
153 * <a name="initial-locale">initial locale </a>is the value returned by the {@link
154 * java.util.Locale#getDefault} method; it may be changed via the {@link
155 * #useLocale} method. The {@link #reset} method will reset the value of the
156 * scanner's locale to the initial locale regardless of whether it was
157 * previously changed.
158 *
159 * <p>The localized formats are defined in terms of the following parameters,
160 * which for a particular locale are taken from that locale's {@link
161 * java.text.DecimalFormat DecimalFormat} object, <tt>df</tt>, and its and
162 * {@link java.text.DecimalFormatSymbols DecimalFormatSymbols} object,
163 * <tt>dfs</tt>.
164 *
165 * <blockquote><table>
166 * <tr><td valign="top"><i>LocalGroupSeparator&nbsp;&nbsp;</i></td>
167 *     <td valign="top">The character used to separate thousands groups,
168 *                      <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
169 *                      java.text.DecimalFormatSymbols#getGroupingSeparator
170 *                      getGroupingSeparator()}</td></tr>
171 * <tr><td valign="top"><i>LocalDecimalSeparator&nbsp;&nbsp;</i></td>
172 *     <td valign="top">The character used for the decimal point,
173 *                      <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
174 *                      java.text.DecimalFormatSymbols#getDecimalSeparator
175 *                      getDecimalSeparator()}</td></tr>
176 * <tr><td valign="top"><i>LocalPositivePrefix&nbsp;&nbsp;</i></td>
177 *     <td valign="top">The string that appears before a positive number (may
178 *                      be empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
179 *                      java.text.DecimalFormat#getPositivePrefix
180 *                      getPositivePrefix()}</td></tr>
181 * <tr><td valign="top"><i>LocalPositiveSuffix&nbsp;&nbsp;</i></td>
182 *     <td valign="top">The string that appears after a positive number (may be
183 *                      empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
184 *                      java.text.DecimalFormat#getPositiveSuffix
185 *                      getPositiveSuffix()}</td></tr>
186 * <tr><td valign="top"><i>LocalNegativePrefix&nbsp;&nbsp;</i></td>
187 *     <td valign="top">The string that appears before a negative number (may
188 *                      be empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
189 *                      java.text.DecimalFormat#getNegativePrefix
190 *                      getNegativePrefix()}</td></tr>
191 * <tr><td valign="top"><i>LocalNegativeSuffix&nbsp;&nbsp;</i></td>
192 *     <td valign="top">The string that appears after a negative number (may be
193 *                      empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
194 *                      java.text.DecimalFormat#getNegativeSuffix
195 *                      getNegativeSuffix()}</td></tr>
196 * <tr><td valign="top"><i>LocalNaN&nbsp;&nbsp;</i></td>
197 *     <td valign="top">The string that represents not-a-number for
198 *                      floating-point values,
199 *                      <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
200 *                      java.text.DecimalFormatSymbols#getNaN
201 *                      getNaN()}</td></tr>
202 * <tr><td valign="top"><i>LocalInfinity&nbsp;&nbsp;</i></td>
203 *     <td valign="top">The string that represents infinity for floating-point
204 *                      values, <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
205 *                      java.text.DecimalFormatSymbols#getInfinity
206 *                      getInfinity()}</td></tr>
207 * </table></blockquote>
208 *
209 * <a name="number-syntax">
210 * <h4> Number syntax </h4>
211 *
212 * <p> The strings that can be parsed as numbers by an instance of this class
213 * are specified in terms of the following regular-expression grammar, where
214 * Rmax is the highest digit in the radix being used (for example, Rmax is 9
215 * in base 10).
216 *
217 * <p>
218 * <table cellspacing=0 cellpadding=0 align=center>
219 *
220 *   <tr><td valign=top align=right><i>NonASCIIDigit</i>&nbsp;&nbsp;::</td>
221 *       <td valign=top>= A non-ASCII character c for which
222 *            {@link java.lang.Character#isDigit Character.isDigit}<tt>(c)</tt>
223 *                        returns&nbsp;true</td></tr>
224 *
225 *   <tr><td>&nbsp;</td></tr>
226 *
227 *   <tr><td align=right><i>Non0Digit</i>&nbsp;&nbsp;::</td>
228 *   <td><tt>= [1-</tt><i>Rmax</i><tt>] | </tt><i>NonASCIIDigit</i></td></tr>
229 *
230 *   <tr><td>&nbsp;</td></tr>
231 *
232 *   <tr><td align=right><i>Digit</i>&nbsp;&nbsp;::</td>
233 *   <td><tt>= [0-</tt><i>Rmax</i><tt>] | </tt><i>NonASCIIDigit</i></td></tr>
234 *
235 *   <tr><td>&nbsp;</td></tr>
236 *
237 *   <tr><td valign=top align=right><i>GroupedNumeral</i>&nbsp;&nbsp;::</td>
238 *       <td valign=top>
239 *         <table cellpadding=0 cellspacing=0>
240 *           <tr><td><tt>= (&nbsp;</tt></td>
241 *               <td><i>Non0Digit</i><tt>
242 *                   </tt><i>Digit</i><tt>?
243 *                   </tt><i>Digit</i><tt>?</tt></td></tr>
244 *           <tr><td></td>
245 *               <td><tt>(&nbsp;</tt><i>LocalGroupSeparator</i><tt>
246 *                         </tt><i>Digit</i><tt>
247 *                         </tt><i>Digit</i><tt>
248 *                         </tt><i>Digit</i><tt> )+ )</tt></td></tr>
249 *         </table></td></tr>
250 *
251 *   <tr><td>&nbsp;</td></tr>
252 *
253 *   <tr><td align=right><i>Numeral</i>&nbsp;&nbsp;::</td>
254 *       <td><tt>= ( ( </tt><i>Digit</i><tt>+ )
255 *               | </tt><i>GroupedNumeral</i><tt> )</tt></td></tr>
256 *
257 *   <tr><td>&nbsp;</td></tr>
258 *
259 *   <tr><td valign=top align=right>
260 *         <a name="Integer-regex"><i>Integer</i>&nbsp;&nbsp;::</td>
261 *       <td valign=top><tt>= ( [-+]? ( </tt><i>Numeral</i><tt>
262 *                               ) )</tt></td></tr>
263 *   <tr><td></td>
264 *       <td><tt>| </tt><i>LocalPositivePrefix</i><tt> </tt><i>Numeral</i><tt>
265 *                      </tt><i>LocalPositiveSuffix</i></td></tr>
266 *   <tr><td></td>
267 *       <td><tt>| </tt><i>LocalNegativePrefix</i><tt> </tt><i>Numeral</i><tt>
268 *                 </tt><i>LocalNegativeSuffix</i></td></tr>
269 *
270 *   <tr><td>&nbsp;</td></tr>
271 *
272 *   <tr><td align=right><i>DecimalNumeral</i>&nbsp;&nbsp;::</td>
273 *       <td><tt>= </tt><i>Numeral</i></td></tr>
274 *   <tr><td></td>
275 *       <td><tt>| </tt><i>Numeral</i><tt>
276 *                 </tt><i>LocalDecimalSeparator</i><tt>
277 *                 </tt><i>Digit</i><tt>*</tt></td></tr>
278 *   <tr><td></td>
279 *       <td><tt>| </tt><i>LocalDecimalSeparator</i><tt>
280 *                 </tt><i>Digit</i><tt>+</tt></td></tr>
281 *
282 *   <tr><td>&nbsp;</td></tr>
283 *
284 *   <tr><td align=right><i>Exponent</i>&nbsp;&nbsp;::</td>
285 *       <td><tt>= ( [eE] [+-]? </tt><i>Digit</i><tt>+ )</tt></td></tr>
286 *
287 *   <tr><td>&nbsp;</td></tr>
288 *
289 *   <tr><td align=right>
290 *         <a name="Decimal-regex"><i>Decimal</i>&nbsp;&nbsp;::</td>
291 *       <td><tt>= ( [-+]? </tt><i>DecimalNumeral</i><tt>
292 *                         </tt><i>Exponent</i><tt>? )</tt></td></tr>
293 *   <tr><td></td>
294 *       <td><tt>| </tt><i>LocalPositivePrefix</i><tt>
295 *                 </tt><i>DecimalNumeral</i><tt>
296 *                 </tt><i>LocalPositiveSuffix</i>
297 *                 </tt><i>Exponent</i><tt>?</td></tr>
298 *   <tr><td></td>
299 *       <td><tt>| </tt><i>LocalNegativePrefix</i><tt>
300 *                 </tt><i>DecimalNumeral</i><tt>
301 *                 </tt><i>LocalNegativeSuffix</i>
302 *                 </tt><i>Exponent</i><tt>?</td></tr>
303 *
304 *   <tr><td>&nbsp;</td></tr>
305 *
306 *   <tr><td align=right><i>HexFloat</i>&nbsp;&nbsp;::</td>
307 *       <td><tt>= [-+]? 0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+
308 *                 ([pP][-+]?[0-9]+)?</tt></td></tr>
309 *
310 *   <tr><td>&nbsp;</td></tr>
311 *
312 *   <tr><td align=right><i>NonNumber</i>&nbsp;&nbsp;::</td>
313 *       <td valign=top><tt>= NaN
314 *                          | </tt><i>LocalNan</i><tt>
315 *                          | Infinity
316 *                          | </tt><i>LocalInfinity</i></td></tr>
317 *
318 *   <tr><td>&nbsp;</td></tr>
319 *
320 *   <tr><td align=right><i>SignedNonNumber</i>&nbsp;&nbsp;::</td>
321 *       <td><tt>= ( [-+]? </tt><i>NonNumber</i><tt> )</tt></td></tr>
322 *   <tr><td></td>
323 *       <td><tt>| </tt><i>LocalPositivePrefix</i><tt>
324 *                 </tt><i>NonNumber</i><tt>
325 *                 </tt><i>LocalPositiveSuffix</i></td></tr>
326 *   <tr><td></td>
327 *       <td><tt>| </tt><i>LocalNegativePrefix</i><tt>
328 *                 </tt><i>NonNumber</i><tt>
329 *                 </tt><i>LocalNegativeSuffix</i></td></tr>
330 *
331 *   <tr><td>&nbsp;</td></tr>
332 *
333 *   <tr><td valign=top align=right>
334 *         <a name="Float-regex"><i>Float</i>&nbsp;&nbsp;::</td>
335 *       <td valign=top><tt>= </tt><i>Decimal</i><tt></td></tr>
336 *       <tr><td></td>
337 *           <td><tt>| </tt><i>HexFloat</i><tt></td></tr>
338 *       <tr><td></td>
339 *           <td><tt>| </tt><i>SignedNonNumber</i><tt></td></tr>
340 *
341 * </table>
342 * </center>
343 *
344 * <p> Whitespace is not significant in the above regular expressions.
345 *
346 * @since   1.5
347 */
348public final class Scanner implements Iterator<String>, Closeable {
349
350    // Internal buffer used to hold input
351    private CharBuffer buf;
352
353    // Size of internal character buffer
354    private static final int BUFFER_SIZE = 1024; // change to 1024;
355
356    // The index into the buffer currently held by the Scanner
357    private int position;
358
359    // Internal matcher used for finding delimiters
360    private Matcher matcher;
361
362    // Pattern used to delimit tokens
363    private Pattern delimPattern;
364
365    // Pattern found in last hasNext operation
366    private Pattern hasNextPattern;
367
368    // Position after last hasNext operation
369    private int hasNextPosition;
370
371    // Result after last hasNext operation
372    private String hasNextResult;
373
374    // The input source
375    private Readable source;
376
377    // Boolean is true if source is done
378    private boolean sourceClosed = false;
379
380    // Boolean indicating more input is required
381    private boolean needInput = false;
382
383    // Boolean indicating if a delim has been skipped this operation
384    private boolean skipped = false;
385
386    // A store of a position that the scanner may fall back to
387    private int savedScannerPosition = -1;
388
389    // A cache of the last primitive type scanned
390    private Object typeCache = null;
391
392    // Boolean indicating if a match result is available
393    private boolean matchValid = false;
394
395    // Boolean indicating if this scanner has been closed
396    private boolean closed = false;
397
398    // The current radix used by this scanner
399    private int radix = 10;
400
401    // The default radix for this scanner
402    private int defaultRadix = 10;
403
404    // The locale used by this scanner
405    private Locale locale = null;
406
407    // A cache of the last few recently used Patterns
408    private LRUCache<String,Pattern> patternCache =
409    new LRUCache<String,Pattern>(7) {
410        protected Pattern create(String s) {
411            return Pattern.compile(s);
412        }
413        protected boolean hasName(Pattern p, String s) {
414            return p.pattern().equals(s);
415        }
416    };
417
418    // A holder of the last IOException encountered
419    private IOException lastException;
420
421    // A pattern for java whitespace
422    private static Pattern WHITESPACE_PATTERN = Pattern.compile(
423                                                "\\p{javaWhitespace}+");
424
425    // A pattern for any token
426    private static Pattern FIND_ANY_PATTERN = Pattern.compile("(?s).*");
427
428    // A pattern for non-ASCII digits
429    private static Pattern NON_ASCII_DIGIT = Pattern.compile(
430        "[\\p{javaDigit}&&[^0-9]]");
431
432    // Fields and methods to support scanning primitive types
433
434    /**
435     * Locale dependent values used to scan numbers
436     */
437    private String groupSeparator = "\\,";
438    private String decimalSeparator = "\\.";
439    private String nanString = "NaN";
440    private String infinityString = "Infinity";
441    private String positivePrefix = "";
442    private String negativePrefix = "\\-";
443    private String positiveSuffix = "";
444    private String negativeSuffix = "";
445
446    /**
447     * Fields and an accessor method to match booleans
448     */
449    private static volatile Pattern boolPattern;
450    private static final String BOOLEAN_PATTERN = "true|false";
451    private static Pattern boolPattern() {
452        Pattern bp = boolPattern;
453        if (bp == null)
454            boolPattern = bp = Pattern.compile(BOOLEAN_PATTERN,
455                                          Pattern.CASE_INSENSITIVE);
456        return bp;
457    }
458
459    /**
460     * Fields and methods to match bytes, shorts, ints, and longs
461     */
462    private Pattern integerPattern;
463    private String digits = "0123456789abcdefghijklmnopqrstuvwxyz";
464    private String non0Digit = "[\\p{javaDigit}&&[^0]]";
465    private int SIMPLE_GROUP_INDEX = 5;
466    private String buildIntegerPatternString() {
467        String radixDigits = digits.substring(0, radix);
468        // \\p{javaDigit} is not guaranteed to be appropriate
469        // here but what can we do? The final authority will be
470        // whatever parse method is invoked, so ultimately the
471        // Scanner will do the right thing
472        String digit = "((?i)["+radixDigits+"]|\\p{javaDigit})";
473        String groupedNumeral = "("+non0Digit+digit+"?"+digit+"?("+
474                                groupSeparator+digit+digit+digit+")+)";
475        // digit++ is the possessive form which is necessary for reducing
476        // backtracking that would otherwise cause unacceptable performance
477        String numeral = "(("+ digit+"++)|"+groupedNumeral+")";
478        String javaStyleInteger = "([-+]?(" + numeral + "))";
479        String negativeInteger = negativePrefix + numeral + negativeSuffix;
480        String positiveInteger = positivePrefix + numeral + positiveSuffix;
481        return "("+ javaStyleInteger + ")|(" +
482            positiveInteger + ")|(" +
483            negativeInteger + ")";
484    }
485    private Pattern integerPattern() {
486        if (integerPattern == null) {
487            integerPattern = patternCache.forName(buildIntegerPatternString());
488        }
489        return integerPattern;
490    }
491
492    /**
493     * Fields and an accessor method to match line separators
494     */
495    private static volatile Pattern separatorPattern;
496    private static volatile Pattern linePattern;
497    private static final String LINE_SEPARATOR_PATTERN =
498                                           "\r\n|[\n\r\u2028\u2029\u0085]";
499    private static final String LINE_PATTERN = ".*("+LINE_SEPARATOR_PATTERN+")|.+$";
500
501    private static Pattern separatorPattern() {
502        Pattern sp = separatorPattern;
503        if (sp == null)
504            separatorPattern = sp = Pattern.compile(LINE_SEPARATOR_PATTERN);
505        return sp;
506    }
507
508    private static Pattern linePattern() {
509        Pattern lp = linePattern;
510        if (lp == null)
511            linePattern = lp = Pattern.compile(LINE_PATTERN);
512        return lp;
513    }
514
515    /**
516     * Fields and methods to match floats and doubles
517     */
518    private Pattern floatPattern;
519    private Pattern decimalPattern;
520    private void buildFloatAndDecimalPattern() {
521        // \\p{javaDigit} may not be perfect, see above
522        String digit = "([0-9]|(\\p{javaDigit}))";
523        String exponent = "([eE][+-]?"+digit+"+)?";
524        String groupedNumeral = "("+non0Digit+digit+"?"+digit+"?("+
525                                groupSeparator+digit+digit+digit+")+)";
526        // Once again digit++ is used for performance, as above
527        String numeral = "(("+digit+"++)|"+groupedNumeral+")";
528        String decimalNumeral = "("+numeral+"|"+numeral +
529            decimalSeparator + digit + "*+|"+ decimalSeparator +
530            digit + "++)";
531        String nonNumber = "(NaN|"+nanString+"|Infinity|"+
532                               infinityString+")";
533        String positiveFloat = "(" + positivePrefix + decimalNumeral +
534                            positiveSuffix + exponent + ")";
535        String negativeFloat = "(" + negativePrefix + decimalNumeral +
536                            negativeSuffix + exponent + ")";
537        String decimal = "(([-+]?" + decimalNumeral + exponent + ")|"+
538            positiveFloat + "|" + negativeFloat + ")";
539        String hexFloat =
540            "[-+]?0[xX][0-9a-fA-F]*\\.[0-9a-fA-F]+([pP][-+]?[0-9]+)?";
541        String positiveNonNumber = "(" + positivePrefix + nonNumber +
542                            positiveSuffix + ")";
543        String negativeNonNumber = "(" + negativePrefix + nonNumber +
544                            negativeSuffix + ")";
545        String signedNonNumber = "(([-+]?"+nonNumber+")|" +
546                                 positiveNonNumber + "|" +
547                                 negativeNonNumber + ")";
548        floatPattern = Pattern.compile(decimal + "|" + hexFloat + "|" +
549                                       signedNonNumber);
550        decimalPattern = Pattern.compile(decimal);
551    }
552    private Pattern floatPattern() {
553        if (floatPattern == null) {
554            buildFloatAndDecimalPattern();
555        }
556        return floatPattern;
557    }
558    private Pattern decimalPattern() {
559        if (decimalPattern == null) {
560            buildFloatAndDecimalPattern();
561        }
562        return decimalPattern;
563    }
564
565    // Constructors
566
567    /**
568     * Constructs a <code>Scanner</code> that returns values scanned
569     * from the specified source delimited by the specified pattern.
570     *
571     * @param  source A character source implementing the Readable interface
572     * @param pattern A delimiting pattern
573     * @return A scanner with the specified source and pattern
574     */
575    private Scanner(Readable source, Pattern pattern) {
576        assert source != null : "source should not be null";
577        assert pattern != null : "pattern should not be null";
578        this.source = source;
579        delimPattern = pattern;
580        buf = CharBuffer.allocate(BUFFER_SIZE);
581        buf.limit(0);
582        matcher = delimPattern.matcher(buf);
583        matcher.useTransparentBounds(true);
584        matcher.useAnchoringBounds(false);
585        useLocale(Locale.getDefault(Locale.Category.FORMAT));
586    }
587
588    /**
589     * Constructs a new <code>Scanner</code> that produces values scanned
590     * from the specified source.
591     *
592     * @param  source A character source implementing the {@link Readable}
593     *         interface
594     */
595    public Scanner(Readable source) {
596        this(Objects.requireNonNull(source, "source"), WHITESPACE_PATTERN);
597    }
598
599    /**
600     * Constructs a new <code>Scanner</code> that produces values scanned
601     * from the specified input stream. Bytes from the stream are converted
602     * into characters using the underlying platform's
603     * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
604     *
605     * @param  source An input stream to be scanned
606     */
607    public Scanner(InputStream source) {
608        this(new InputStreamReader(source), WHITESPACE_PATTERN);
609    }
610
611    /**
612     * Constructs a new <code>Scanner</code> that produces values scanned
613     * from the specified input stream. Bytes from the stream are converted
614     * into characters using the specified charset.
615     *
616     * @param  source An input stream to be scanned
617     * @param charsetName The encoding type used to convert bytes from the
618     *        stream into characters to be scanned
619     * @throws IllegalArgumentException if the specified character set
620     *         does not exist
621     */
622    public Scanner(InputStream source, String charsetName) {
623        this(makeReadable(Objects.requireNonNull(source, "source"), toCharset(charsetName)),
624             WHITESPACE_PATTERN);
625    }
626
627    /**
628     * Returns a charset object for the given charset name.
629     * @throws NullPointerException          is csn is null
630     * @throws IllegalArgumentException      if the charset is not supported
631     */
632    private static Charset toCharset(String csn) {
633        Objects.requireNonNull(csn, "charsetName");
634        try {
635            return Charset.forName(csn);
636        } catch (IllegalCharsetNameException|UnsupportedCharsetException e) {
637            // IllegalArgumentException should be thrown
638            throw new IllegalArgumentException(e);
639        }
640    }
641
642    private static Readable makeReadable(InputStream source, Charset charset) {
643        return new InputStreamReader(source, charset);
644    }
645
646    /**
647     * Constructs a new <code>Scanner</code> that produces values scanned
648     * from the specified file. Bytes from the file are converted into
649     * characters using the underlying platform's
650     * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
651     *
652     * @param  source A file to be scanned
653     * @throws FileNotFoundException if source is not found
654     */
655    public Scanner(File source) throws FileNotFoundException {
656        this((ReadableByteChannel)(new FileInputStream(source).getChannel()));
657    }
658
659    /**
660     * Constructs a new <code>Scanner</code> that produces values scanned
661     * from the specified file. Bytes from the file are converted into
662     * characters using the specified charset.
663     *
664     * @param  source A file to be scanned
665     * @param charsetName The encoding type used to convert bytes from the file
666     *        into characters to be scanned
667     * @throws FileNotFoundException if source is not found
668     * @throws IllegalArgumentException if the specified encoding is
669     *         not found
670     */
671    public Scanner(File source, String charsetName)
672        throws FileNotFoundException
673    {
674        this(Objects.requireNonNull(source), toDecoder(charsetName));
675    }
676
677    private Scanner(File source, CharsetDecoder dec)
678        throws FileNotFoundException
679    {
680        this(makeReadable((ReadableByteChannel)(new FileInputStream(source).getChannel()), dec));
681    }
682
683    private static CharsetDecoder toDecoder(String charsetName) {
684        Objects.requireNonNull(charsetName, "charsetName");
685        try {
686            return Charset.forName(charsetName).newDecoder();
687        } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
688            throw new IllegalArgumentException(charsetName);
689        }
690    }
691
692    private static Readable makeReadable(ReadableByteChannel source,
693                                         CharsetDecoder dec) {
694        return Channels.newReader(source, dec, -1);
695    }
696
697    /**
698     * Constructs a new <code>Scanner</code> that produces values scanned
699     * from the specified file. Bytes from the file are converted into
700     * characters using the underlying platform's
701     * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
702     *
703     * @param   source
704     *          the path to the file to be scanned
705     * @throws  IOException
706     *          if an I/O error occurs opening source
707     *
708     * @since   1.7
709     */
710    public Scanner(Path source)
711        throws IOException
712    {
713        this(Files.newInputStream(source));
714    }
715
716    /**
717     * Constructs a new <code>Scanner</code> that produces values scanned
718     * from the specified file. Bytes from the file are converted into
719     * characters using the specified charset.
720     *
721     * @param   source
722     *          the path to the file to be scanned
723     * @param   charsetName
724     *          The encoding type used to convert bytes from the file
725     *          into characters to be scanned
726     * @throws  IOException
727     *          if an I/O error occurs opening source
728     * @throws  IllegalArgumentException
729     *          if the specified encoding is not found
730     * @since   1.7
731     */
732    public Scanner(Path source, String charsetName) throws IOException {
733        this(Objects.requireNonNull(source), toCharset(charsetName));
734    }
735
736    private Scanner(Path source, Charset charset)  throws IOException {
737        this(makeReadable(Files.newInputStream(source), charset));
738    }
739
740    /**
741     * Constructs a new <code>Scanner</code> that produces values scanned
742     * from the specified string.
743     *
744     * @param  source A string to scan
745     */
746    public Scanner(String source) {
747        this(new StringReader(source), WHITESPACE_PATTERN);
748    }
749
750    /**
751     * Constructs a new <code>Scanner</code> that produces values scanned
752     * from the specified channel. Bytes from the source are converted into
753     * characters using the underlying platform's
754     * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
755     *
756     * @param  source A channel to scan
757     */
758    public Scanner(ReadableByteChannel source) {
759        this(makeReadable(Objects.requireNonNull(source, "source")),
760             WHITESPACE_PATTERN);
761    }
762
763    private static Readable makeReadable(ReadableByteChannel source) {
764        return makeReadable(source, Charset.defaultCharset().newDecoder());
765    }
766
767    /**
768     * Constructs a new <code>Scanner</code> that produces values scanned
769     * from the specified channel. Bytes from the source are converted into
770     * characters using the specified charset.
771     *
772     * @param  source A channel to scan
773     * @param charsetName The encoding type used to convert bytes from the
774     *        channel into characters to be scanned
775     * @throws IllegalArgumentException if the specified character set
776     *         does not exist
777     */
778    public Scanner(ReadableByteChannel source, String charsetName) {
779        this(makeReadable(Objects.requireNonNull(source, "source"), toDecoder(charsetName)),
780             WHITESPACE_PATTERN);
781    }
782
783    // Private primitives used to support scanning
784
785    private void saveState() {
786        savedScannerPosition = position;
787    }
788
789    private void revertState() {
790        this.position = savedScannerPosition;
791        savedScannerPosition = -1;
792        skipped = false;
793    }
794
795    private boolean revertState(boolean b) {
796        this.position = savedScannerPosition;
797        savedScannerPosition = -1;
798        skipped = false;
799        return b;
800    }
801
802    private void cacheResult() {
803        hasNextResult = matcher.group();
804        hasNextPosition = matcher.end();
805        hasNextPattern = matcher.pattern();
806    }
807
808    private void cacheResult(String result) {
809        hasNextResult = result;
810        hasNextPosition = matcher.end();
811        hasNextPattern = matcher.pattern();
812    }
813
814    // Clears both regular cache and type cache
815    private void clearCaches() {
816        hasNextPattern = null;
817        typeCache = null;
818    }
819
820    // Also clears both the regular cache and the type cache
821    private String getCachedResult() {
822        position = hasNextPosition;
823        hasNextPattern = null;
824        typeCache = null;
825        return hasNextResult;
826    }
827
828    // Also clears both the regular cache and the type cache
829    private void useTypeCache() {
830        if (closed)
831            throw new IllegalStateException("Scanner closed");
832        position = hasNextPosition;
833        hasNextPattern = null;
834        typeCache = null;
835    }
836
837    // Tries to read more input. May block.
838    private void readInput() {
839        if (buf.limit() == buf.capacity())
840            makeSpace();
841
842        // Prepare to receive data
843        int p = buf.position();
844        buf.position(buf.limit());
845        buf.limit(buf.capacity());
846
847        int n = 0;
848        try {
849            n = source.read(buf);
850        } catch (IOException ioe) {
851            lastException = ioe;
852            n = -1;
853        }
854
855        if (n == -1) {
856            sourceClosed = true;
857            needInput = false;
858        }
859
860        if (n > 0)
861            needInput = false;
862
863        // Restore current position and limit for reading
864        buf.limit(buf.position());
865        buf.position(p);
866    }
867
868    // After this method is called there will either be an exception
869    // or else there will be space in the buffer
870    private boolean makeSpace() {
871        clearCaches();
872        int offset = savedScannerPosition == -1 ?
873            position : savedScannerPosition;
874        buf.position(offset);
875        // Gain space by compacting buffer
876        if (offset > 0) {
877            buf.compact();
878            translateSavedIndexes(offset);
879            position -= offset;
880            buf.flip();
881            return true;
882        }
883        // Gain space by growing buffer
884        int newSize = buf.capacity() * 2;
885        CharBuffer newBuf = CharBuffer.allocate(newSize);
886        newBuf.put(buf);
887        newBuf.flip();
888        translateSavedIndexes(offset);
889        position -= offset;
890        buf = newBuf;
891        matcher.reset(buf);
892        return true;
893    }
894
895    // When a buffer compaction/reallocation occurs the saved indexes must
896    // be modified appropriately
897    private void translateSavedIndexes(int offset) {
898        if (savedScannerPosition != -1)
899            savedScannerPosition -= offset;
900    }
901
902    // If we are at the end of input then NoSuchElement;
903    // If there is still input left then InputMismatch
904    private void throwFor() {
905        skipped = false;
906        if ((sourceClosed) && (position == buf.limit()))
907            throw new NoSuchElementException();
908        else
909            throw new InputMismatchException();
910    }
911
912    // Returns true if a complete token or partial token is in the buffer.
913    // It is not necessary to find a complete token since a partial token
914    // means that there will be another token with or without more input.
915    private boolean hasTokenInBuffer() {
916        matchValid = false;
917        matcher.usePattern(delimPattern);
918        matcher.region(position, buf.limit());
919
920        // Skip delims first
921        if (matcher.lookingAt())
922            position = matcher.end();
923
924        // If we are sitting at the end, no more tokens in buffer
925        if (position == buf.limit())
926            return false;
927
928        return true;
929    }
930
931    /*
932     * Returns a "complete token" that matches the specified pattern
933     *
934     * A token is complete if surrounded by delims; a partial token
935     * is prefixed by delims but not postfixed by them
936     *
937     * The position is advanced to the end of that complete token
938     *
939     * Pattern == null means accept any token at all
940     *
941     * Triple return:
942     * 1. valid string means it was found
943     * 2. null with needInput=false means we won't ever find it
944     * 3. null with needInput=true means try again after readInput
945     */
946    private String getCompleteTokenInBuffer(Pattern pattern) {
947        matchValid = false;
948
949        // Skip delims first
950        matcher.usePattern(delimPattern);
951        if (!skipped) { // Enforcing only one skip of leading delims
952            matcher.region(position, buf.limit());
953            if (matcher.lookingAt()) {
954                // If more input could extend the delimiters then we must wait
955                // for more input
956                if (matcher.hitEnd() && !sourceClosed) {
957                    needInput = true;
958                    return null;
959                }
960                // The delims were whole and the matcher should skip them
961                skipped = true;
962                position = matcher.end();
963            }
964        }
965
966        // If we are sitting at the end, no more tokens in buffer
967        if (position == buf.limit()) {
968            if (sourceClosed)
969                return null;
970            needInput = true;
971            return null;
972        }
973
974        // Must look for next delims. Simply attempting to match the
975        // pattern at this point may find a match but it might not be
976        // the first longest match because of missing input, or it might
977        // match a partial token instead of the whole thing.
978
979        // Then look for next delims
980        matcher.region(position, buf.limit());
981        boolean foundNextDelim = matcher.find();
982        if (foundNextDelim && (matcher.end() == position)) {
983            // Zero length delimiter match; we should find the next one
984            // using the automatic advance past a zero length match;
985            // Otherwise we have just found the same one we just skipped
986            foundNextDelim = matcher.find();
987        }
988        if (foundNextDelim) {
989            // In the rare case that more input could cause the match
990            // to be lost and there is more input coming we must wait
991            // for more input. Note that hitting the end is okay as long
992            // as the match cannot go away. It is the beginning of the
993            // next delims we want to be sure about, we don't care if
994            // they potentially extend further.
995            if (matcher.requireEnd() && !sourceClosed) {
996                needInput = true;
997                return null;
998            }
999            int tokenEnd = matcher.start();
1000            // There is a complete token.
1001            if (pattern == null) {
1002                // Must continue with match to provide valid MatchResult
1003                pattern = FIND_ANY_PATTERN;
1004            }
1005            //  Attempt to match against the desired pattern
1006            matcher.usePattern(pattern);
1007            matcher.region(position, tokenEnd);
1008            if (matcher.matches()) {
1009                String s = matcher.group();
1010                position = matcher.end();
1011                return s;
1012            } else { // Complete token but it does not match
1013                return null;
1014            }
1015        }
1016
1017        // If we can't find the next delims but no more input is coming,
1018        // then we can treat the remainder as a whole token
1019        if (sourceClosed) {
1020            if (pattern == null) {
1021                // Must continue with match to provide valid MatchResult
1022                pattern = FIND_ANY_PATTERN;
1023            }
1024            // Last token; Match the pattern here or throw
1025            matcher.usePattern(pattern);
1026            matcher.region(position, buf.limit());
1027            if (matcher.matches()) {
1028                String s = matcher.group();
1029                position = matcher.end();
1030                return s;
1031            }
1032            // Last piece does not match
1033            return null;
1034        }
1035
1036        // There is a partial token in the buffer; must read more
1037        // to complete it
1038        needInput = true;
1039        return null;
1040    }
1041
1042    // Finds the specified pattern in the buffer up to horizon.
1043    // Returns a match for the specified input pattern.
1044    private String findPatternInBuffer(Pattern pattern, int horizon) {
1045        matchValid = false;
1046        matcher.usePattern(pattern);
1047        int bufferLimit = buf.limit();
1048        int horizonLimit = -1;
1049        int searchLimit = bufferLimit;
1050        if (horizon > 0) {
1051            horizonLimit = position + horizon;
1052            if (horizonLimit < bufferLimit)
1053                searchLimit = horizonLimit;
1054        }
1055        matcher.region(position, searchLimit);
1056        if (matcher.find()) {
1057            if (matcher.hitEnd() && (!sourceClosed)) {
1058                // The match may be longer if didn't hit horizon or real end
1059                if (searchLimit != horizonLimit) {
1060                     // Hit an artificial end; try to extend the match
1061                    needInput = true;
1062                    return null;
1063                }
1064                // The match could go away depending on what is next
1065                if ((searchLimit == horizonLimit) && matcher.requireEnd()) {
1066                    // Rare case: we hit the end of input and it happens
1067                    // that it is at the horizon and the end of input is
1068                    // required for the match.
1069                    needInput = true;
1070                    return null;
1071                }
1072            }
1073            // Did not hit end, or hit real end, or hit horizon
1074            position = matcher.end();
1075            return matcher.group();
1076        }
1077
1078        if (sourceClosed)
1079            return null;
1080
1081        // If there is no specified horizon, or if we have not searched
1082        // to the specified horizon yet, get more input
1083        if ((horizon == 0) || (searchLimit != horizonLimit))
1084            needInput = true;
1085        return null;
1086    }
1087
1088    // Returns a match for the specified input pattern anchored at
1089    // the current position
1090    private String matchPatternInBuffer(Pattern pattern) {
1091        matchValid = false;
1092        matcher.usePattern(pattern);
1093        matcher.region(position, buf.limit());
1094        if (matcher.lookingAt()) {
1095            if (matcher.hitEnd() && (!sourceClosed)) {
1096                // Get more input and try again
1097                needInput = true;
1098                return null;
1099            }
1100            position = matcher.end();
1101            return matcher.group();
1102        }
1103
1104        if (sourceClosed)
1105            return null;
1106
1107        // Read more to find pattern
1108        needInput = true;
1109        return null;
1110    }
1111
1112    // Throws if the scanner is closed
1113    private void ensureOpen() {
1114        if (closed)
1115            throw new IllegalStateException("Scanner closed");
1116    }
1117
1118    // Public methods
1119
1120    /**
1121     * Closes this scanner.
1122     *
1123     * <p> If this scanner has not yet been closed then if its underlying
1124     * {@linkplain java.lang.Readable readable} also implements the {@link
1125     * java.io.Closeable} interface then the readable's <tt>close</tt> method
1126     * will be invoked.  If this scanner is already closed then invoking this
1127     * method will have no effect.
1128     *
1129     * <p>Attempting to perform search operations after a scanner has
1130     * been closed will result in an {@link IllegalStateException}.
1131     *
1132     */
1133    public void close() {
1134        if (closed)
1135            return;
1136        if (source instanceof Closeable) {
1137            try {
1138                ((Closeable)source).close();
1139            } catch (IOException ioe) {
1140                lastException = ioe;
1141            }
1142        }
1143        sourceClosed = true;
1144        source = null;
1145        closed = true;
1146    }
1147
1148    /**
1149     * Returns the <code>IOException</code> last thrown by this
1150     * <code>Scanner</code>'s underlying <code>Readable</code>. This method
1151     * returns <code>null</code> if no such exception exists.
1152     *
1153     * @return the last exception thrown by this scanner's readable
1154     */
1155    public IOException ioException() {
1156        return lastException;
1157    }
1158
1159    /**
1160     * Returns the <code>Pattern</code> this <code>Scanner</code> is currently
1161     * using to match delimiters.
1162     *
1163     * @return this scanner's delimiting pattern.
1164     */
1165    public Pattern delimiter() {
1166        return delimPattern;
1167    }
1168
1169    /**
1170     * Sets this scanner's delimiting pattern to the specified pattern.
1171     *
1172     * @param pattern A delimiting pattern
1173     * @return this scanner
1174     */
1175    public Scanner useDelimiter(Pattern pattern) {
1176        delimPattern = pattern;
1177        return this;
1178    }
1179
1180    /**
1181     * Sets this scanner's delimiting pattern to a pattern constructed from
1182     * the specified <code>String</code>.
1183     *
1184     * <p> An invocation of this method of the form
1185     * <tt>useDelimiter(pattern)</tt> behaves in exactly the same way as the
1186     * invocation <tt>useDelimiter(Pattern.compile(pattern))</tt>.
1187     *
1188     * <p> Invoking the {@link #reset} method will set the scanner's delimiter
1189     * to the <a href= "#default-delimiter">default</a>.
1190     *
1191     * @param pattern A string specifying a delimiting pattern
1192     * @return this scanner
1193     */
1194    public Scanner useDelimiter(String pattern) {
1195        delimPattern = patternCache.forName(pattern);
1196        return this;
1197    }
1198
1199    /**
1200     * Returns this scanner's locale.
1201     *
1202     * <p>A scanner's locale affects many elements of its default
1203     * primitive matching regular expressions; see
1204     * <a href= "#localized-numbers">localized numbers</a> above.
1205     *
1206     * @return this scanner's locale
1207     */
1208    public Locale locale() {
1209        return this.locale;
1210    }
1211
1212    /**
1213     * Sets this scanner's locale to the specified locale.
1214     *
1215     * <p>A scanner's locale affects many elements of its default
1216     * primitive matching regular expressions; see
1217     * <a href= "#localized-numbers">localized numbers</a> above.
1218     *
1219     * <p>Invoking the {@link #reset} method will set the scanner's locale to
1220     * the <a href= "#initial-locale">initial locale</a>.
1221     *
1222     * @param locale A string specifying the locale to use
1223     * @return this scanner
1224     */
1225    public Scanner useLocale(Locale locale) {
1226        if (locale.equals(this.locale))
1227            return this;
1228
1229        this.locale = locale;
1230        DecimalFormat df =
1231            (DecimalFormat)NumberFormat.getNumberInstance(locale);
1232        DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale);
1233
1234        // These must be literalized to avoid collision with regex
1235        // metacharacters such as dot or parenthesis
1236        groupSeparator =   "\\" + dfs.getGroupingSeparator();
1237        decimalSeparator = "\\" + dfs.getDecimalSeparator();
1238
1239        // Quoting the nonzero length locale-specific things
1240        // to avoid potential conflict with metacharacters
1241        nanString = "\\Q" + dfs.getNaN() + "\\E";
1242        infinityString = "\\Q" + dfs.getInfinity() + "\\E";
1243        positivePrefix = df.getPositivePrefix();
1244        if (positivePrefix.length() > 0)
1245            positivePrefix = "\\Q" + positivePrefix + "\\E";
1246        negativePrefix = df.getNegativePrefix();
1247        if (negativePrefix.length() > 0)
1248            negativePrefix = "\\Q" + negativePrefix + "\\E";
1249        positiveSuffix = df.getPositiveSuffix();
1250        if (positiveSuffix.length() > 0)
1251            positiveSuffix = "\\Q" + positiveSuffix + "\\E";
1252        negativeSuffix = df.getNegativeSuffix();
1253        if (negativeSuffix.length() > 0)
1254            negativeSuffix = "\\Q" + negativeSuffix + "\\E";
1255
1256        // Force rebuilding and recompilation of locale dependent
1257        // primitive patterns
1258        integerPattern = null;
1259        floatPattern = null;
1260
1261        return this;
1262    }
1263
1264    /**
1265     * Returns this scanner's default radix.
1266     *
1267     * <p>A scanner's radix affects elements of its default
1268     * number matching regular expressions; see
1269     * <a href= "#localized-numbers">localized numbers</a> above.
1270     *
1271     * @return the default radix of this scanner
1272     */
1273    public int radix() {
1274        return this.defaultRadix;
1275    }
1276
1277    /**
1278     * Sets this scanner's default radix to the specified radix.
1279     *
1280     * <p>A scanner's radix affects elements of its default
1281     * number matching regular expressions; see
1282     * <a href= "#localized-numbers">localized numbers</a> above.
1283     *
1284     * <p>If the radix is less than <code>Character.MIN_RADIX</code>
1285     * or greater than <code>Character.MAX_RADIX</code>, then an
1286     * <code>IllegalArgumentException</code> is thrown.
1287     *
1288     * <p>Invoking the {@link #reset} method will set the scanner's radix to
1289     * <code>10</code>.
1290     *
1291     * @param radix The radix to use when scanning numbers
1292     * @return this scanner
1293     * @throws IllegalArgumentException if radix is out of range
1294     */
1295    public Scanner useRadix(int radix) {
1296        if ((radix < Character.MIN_RADIX) || (radix > Character.MAX_RADIX))
1297            throw new IllegalArgumentException("radix:"+radix);
1298
1299        if (this.defaultRadix == radix)
1300            return this;
1301        this.defaultRadix = radix;
1302        // Force rebuilding and recompilation of radix dependent patterns
1303        integerPattern = null;
1304        return this;
1305    }
1306
1307    // The next operation should occur in the specified radix but
1308    // the default is left untouched.
1309    private void setRadix(int radix) {
1310        if (this.radix != radix) {
1311            // Force rebuilding and recompilation of radix dependent patterns
1312            integerPattern = null;
1313            this.radix = radix;
1314        }
1315    }
1316
1317    /**
1318     * Returns the match result of the last scanning operation performed
1319     * by this scanner. This method throws <code>IllegalStateException</code>
1320     * if no match has been performed, or if the last match was
1321     * not successful.
1322     *
1323     * <p>The various <code>next</code>methods of <code>Scanner</code>
1324     * make a match result available if they complete without throwing an
1325     * exception. For instance, after an invocation of the {@link #nextInt}
1326     * method that returned an int, this method returns a
1327     * <code>MatchResult</code> for the search of the
1328     * <a href="#Integer-regex"><i>Integer</i></a> regular expression
1329     * defined above. Similarly the {@link #findInLine},
1330     * {@link #findWithinHorizon}, and {@link #skip} methods will make a
1331     * match available if they succeed.
1332     *
1333     * @return a match result for the last match operation
1334     * @throws IllegalStateException  If no match result is available
1335     */
1336    public MatchResult match() {
1337        if (!matchValid)
1338            throw new IllegalStateException("No match result available");
1339        return matcher.toMatchResult();
1340    }
1341
1342    /**
1343     * <p>Returns the string representation of this <code>Scanner</code>. The
1344     * string representation of a <code>Scanner</code> contains information
1345     * that may be useful for debugging. The exact format is unspecified.
1346     *
1347     * @return  The string representation of this scanner
1348     */
1349    public String toString() {
1350        StringBuilder sb = new StringBuilder();
1351        sb.append("java.util.Scanner");
1352        sb.append("[delimiters=" + delimPattern + "]");
1353        sb.append("[position=" + position + "]");
1354        sb.append("[match valid=" + matchValid + "]");
1355        sb.append("[need input=" + needInput + "]");
1356        sb.append("[source closed=" + sourceClosed + "]");
1357        sb.append("[skipped=" + skipped + "]");
1358        sb.append("[group separator=" + groupSeparator + "]");
1359        sb.append("[decimal separator=" + decimalSeparator + "]");
1360        sb.append("[positive prefix=" + positivePrefix + "]");
1361        sb.append("[negative prefix=" + negativePrefix + "]");
1362        sb.append("[positive suffix=" + positiveSuffix + "]");
1363        sb.append("[negative suffix=" + negativeSuffix + "]");
1364        sb.append("[NaN string=" + nanString + "]");
1365        sb.append("[infinity string=" + infinityString + "]");
1366        return sb.toString();
1367    }
1368
1369    /**
1370     * Returns true if this scanner has another token in its input.
1371     * This method may block while waiting for input to scan.
1372     * The scanner does not advance past any input.
1373     *
1374     * @return true if and only if this scanner has another token
1375     * @throws IllegalStateException if this scanner is closed
1376     * @see java.util.Iterator
1377     */
1378    public boolean hasNext() {
1379        ensureOpen();
1380        saveState();
1381        while (!sourceClosed) {
1382            if (hasTokenInBuffer())
1383                return revertState(true);
1384            readInput();
1385        }
1386        boolean result = hasTokenInBuffer();
1387        return revertState(result);
1388    }
1389
1390    /**
1391     * Finds and returns the next complete token from this scanner.
1392     * A complete token is preceded and followed by input that matches
1393     * the delimiter pattern. This method may block while waiting for input
1394     * to scan, even if a previous invocation of {@link #hasNext} returned
1395     * <code>true</code>.
1396     *
1397     * @return the next token
1398     * @throws NoSuchElementException if no more tokens are available
1399     * @throws IllegalStateException if this scanner is closed
1400     * @see java.util.Iterator
1401     */
1402    public String next() {
1403        ensureOpen();
1404        clearCaches();
1405
1406        while (true) {
1407            String token = getCompleteTokenInBuffer(null);
1408            if (token != null) {
1409                matchValid = true;
1410                skipped = false;
1411                return token;
1412            }
1413            if (needInput)
1414                readInput();
1415            else
1416                throwFor();
1417        }
1418    }
1419
1420    /**
1421     * The remove operation is not supported by this implementation of
1422     * <code>Iterator</code>.
1423     *
1424     * @throws UnsupportedOperationException if this method is invoked.
1425     * @see java.util.Iterator
1426     */
1427    public void remove() {
1428        throw new UnsupportedOperationException();
1429    }
1430
1431    /**
1432     * Returns true if the next token matches the pattern constructed from the
1433     * specified string. The scanner does not advance past any input.
1434     *
1435     * <p> An invocation of this method of the form <tt>hasNext(pattern)</tt>
1436     * behaves in exactly the same way as the invocation
1437     * <tt>hasNext(Pattern.compile(pattern))</tt>.
1438     *
1439     * @param pattern a string specifying the pattern to scan
1440     * @return true if and only if this scanner has another token matching
1441     *         the specified pattern
1442     * @throws IllegalStateException if this scanner is closed
1443     */
1444    public boolean hasNext(String pattern)  {
1445        return hasNext(patternCache.forName(pattern));
1446    }
1447
1448    /**
1449     * Returns the next token if it matches the pattern constructed from the
1450     * specified string.  If the match is successful, the scanner advances
1451     * past the input that matched the pattern.
1452     *
1453     * <p> An invocation of this method of the form <tt>next(pattern)</tt>
1454     * behaves in exactly the same way as the invocation
1455     * <tt>next(Pattern.compile(pattern))</tt>.
1456     *
1457     * @param pattern a string specifying the pattern to scan
1458     * @return the next token
1459     * @throws NoSuchElementException if no such tokens are available
1460     * @throws IllegalStateException if this scanner is closed
1461     */
1462    public String next(String pattern)  {
1463        return next(patternCache.forName(pattern));
1464    }
1465
1466    /**
1467     * Returns true if the next complete token matches the specified pattern.
1468     * A complete token is prefixed and postfixed by input that matches
1469     * the delimiter pattern. This method may block while waiting for input.
1470     * The scanner does not advance past any input.
1471     *
1472     * @param pattern the pattern to scan for
1473     * @return true if and only if this scanner has another token matching
1474     *         the specified pattern
1475     * @throws IllegalStateException if this scanner is closed
1476     */
1477    public boolean hasNext(Pattern pattern) {
1478        ensureOpen();
1479        if (pattern == null)
1480            throw new NullPointerException();
1481        hasNextPattern = null;
1482        saveState();
1483
1484        while (true) {
1485            if (getCompleteTokenInBuffer(pattern) != null) {
1486                matchValid = true;
1487                cacheResult();
1488                return revertState(true);
1489            }
1490            if (needInput)
1491                readInput();
1492            else
1493                return revertState(false);
1494        }
1495    }
1496
1497    /**
1498     * Returns the next token if it matches the specified pattern. This
1499     * method may block while waiting for input to scan, even if a previous
1500     * invocation of {@link #hasNext(Pattern)} returned <code>true</code>.
1501     * If the match is successful, the scanner advances past the input that
1502     * matched the pattern.
1503     *
1504     * @param pattern the pattern to scan for
1505     * @return the next token
1506     * @throws NoSuchElementException if no more tokens are available
1507     * @throws IllegalStateException if this scanner is closed
1508     */
1509    public String next(Pattern pattern) {
1510        ensureOpen();
1511        if (pattern == null)
1512            throw new NullPointerException();
1513
1514        // Did we already find this pattern?
1515        if (hasNextPattern == pattern)
1516            return getCachedResult();
1517        clearCaches();
1518
1519        // Search for the pattern
1520        while (true) {
1521            String token = getCompleteTokenInBuffer(pattern);
1522            if (token != null) {
1523                matchValid = true;
1524                skipped = false;
1525                return token;
1526            }
1527            if (needInput)
1528                readInput();
1529            else
1530                throwFor();
1531        }
1532    }
1533
1534    /**
1535     * Returns true if there is another line in the input of this scanner.
1536     * This method may block while waiting for input. The scanner does not
1537     * advance past any input.
1538     *
1539     * @return true if and only if this scanner has another line of input
1540     * @throws IllegalStateException if this scanner is closed
1541     */
1542    public boolean hasNextLine() {
1543        saveState();
1544
1545        String result = findWithinHorizon(linePattern(), 0);
1546        if (result != null) {
1547            MatchResult mr = this.match();
1548            String lineSep = mr.group(1);
1549            if (lineSep != null) {
1550                result = result.substring(0, result.length() -
1551                                          lineSep.length());
1552                cacheResult(result);
1553
1554            } else {
1555                cacheResult();
1556            }
1557        }
1558        revertState();
1559        return (result != null);
1560    }
1561
1562    /**
1563     * Advances this scanner past the current line and returns the input
1564     * that was skipped.
1565     *
1566     * This method returns the rest of the current line, excluding any line
1567     * separator at the end. The position is set to the beginning of the next
1568     * line.
1569     *
1570     * <p>Since this method continues to search through the input looking
1571     * for a line separator, it may buffer all of the input searching for
1572     * the line to skip if no line separators are present.
1573     *
1574     * @return the line that was skipped
1575     * @throws NoSuchElementException if no line was found
1576     * @throws IllegalStateException if this scanner is closed
1577     */
1578    public String nextLine() {
1579        if (hasNextPattern == linePattern())
1580            return getCachedResult();
1581        clearCaches();
1582
1583        String result = findWithinHorizon(linePattern, 0);
1584        if (result == null)
1585            throw new NoSuchElementException("No line found");
1586        MatchResult mr = this.match();
1587        String lineSep = mr.group(1);
1588        if (lineSep != null)
1589            result = result.substring(0, result.length() - lineSep.length());
1590        if (result == null)
1591            throw new NoSuchElementException();
1592        else
1593            return result;
1594    }
1595
1596    // Public methods that ignore delimiters
1597
1598    /**
1599     * Attempts to find the next occurrence of a pattern constructed from the
1600     * specified string, ignoring delimiters.
1601     *
1602     * <p>An invocation of this method of the form <tt>findInLine(pattern)</tt>
1603     * behaves in exactly the same way as the invocation
1604     * <tt>findInLine(Pattern.compile(pattern))</tt>.
1605     *
1606     * @param pattern a string specifying the pattern to search for
1607     * @return the text that matched the specified pattern
1608     * @throws IllegalStateException if this scanner is closed
1609     */
1610    public String findInLine(String pattern) {
1611        return findInLine(patternCache.forName(pattern));
1612    }
1613
1614    /**
1615     * Attempts to find the next occurrence of the specified pattern ignoring
1616     * delimiters. If the pattern is found before the next line separator, the
1617     * scanner advances past the input that matched and returns the string that
1618     * matched the pattern.
1619     * If no such pattern is detected in the input up to the next line
1620     * separator, then <code>null</code> is returned and the scanner's
1621     * position is unchanged. This method may block waiting for input that
1622     * matches the pattern.
1623     *
1624     * <p>Since this method continues to search through the input looking
1625     * for the specified pattern, it may buffer all of the input searching for
1626     * the desired token if no line separators are present.
1627     *
1628     * @param pattern the pattern to scan for
1629     * @return the text that matched the specified pattern
1630     * @throws IllegalStateException if this scanner is closed
1631     */
1632    public String findInLine(Pattern pattern) {
1633        ensureOpen();
1634        if (pattern == null)
1635            throw new NullPointerException();
1636        clearCaches();
1637        // Expand buffer to include the next newline or end of input
1638        int endPosition = 0;
1639        saveState();
1640        while (true) {
1641            String token = findPatternInBuffer(separatorPattern(), 0);
1642            if (token != null) {
1643                endPosition = matcher.start();
1644                break; // up to next newline
1645            }
1646            if (needInput) {
1647                readInput();
1648            } else {
1649                endPosition = buf.limit();
1650                break; // up to end of input
1651            }
1652        }
1653        revertState();
1654        int horizonForLine = endPosition - position;
1655        // If there is nothing between the current pos and the next
1656        // newline simply return null, invoking findWithinHorizon
1657        // with "horizon=0" will scan beyond the line bound.
1658        if (horizonForLine == 0)
1659            return null;
1660        // Search for the pattern
1661        return findWithinHorizon(pattern, horizonForLine);
1662    }
1663
1664    /**
1665     * Attempts to find the next occurrence of a pattern constructed from the
1666     * specified string, ignoring delimiters.
1667     *
1668     * <p>An invocation of this method of the form
1669     * <tt>findWithinHorizon(pattern)</tt> behaves in exactly the same way as
1670     * the invocation
1671     * <tt>findWithinHorizon(Pattern.compile(pattern, horizon))</tt>.
1672     *
1673     * @param pattern a string specifying the pattern to search for
1674     * @return the text that matched the specified pattern
1675     * @throws IllegalStateException if this scanner is closed
1676     * @throws IllegalArgumentException if horizon is negative
1677     */
1678    public String findWithinHorizon(String pattern, int horizon) {
1679        return findWithinHorizon(patternCache.forName(pattern), horizon);
1680    }
1681
1682    /**
1683     * Attempts to find the next occurrence of the specified pattern.
1684     *
1685     * <p>This method searches through the input up to the specified
1686     * search horizon, ignoring delimiters. If the pattern is found the
1687     * scanner advances past the input that matched and returns the string
1688     * that matched the pattern. If no such pattern is detected then the
1689     * null is returned and the scanner's position remains unchanged. This
1690     * method may block waiting for input that matches the pattern.
1691     *
1692     * <p>A scanner will never search more than <code>horizon</code> code
1693     * points beyond its current position. Note that a match may be clipped
1694     * by the horizon; that is, an arbitrary match result may have been
1695     * different if the horizon had been larger. The scanner treats the
1696     * horizon as a transparent, non-anchoring bound (see {@link
1697     * Matcher#useTransparentBounds} and {@link Matcher#useAnchoringBounds}).
1698     *
1699     * <p>If horizon is <code>0</code>, then the horizon is ignored and
1700     * this method continues to search through the input looking for the
1701     * specified pattern without bound. In this case it may buffer all of
1702     * the input searching for the pattern.
1703     *
1704     * <p>If horizon is negative, then an IllegalArgumentException is
1705     * thrown.
1706     *
1707     * @param pattern the pattern to scan for
1708     * @return the text that matched the specified pattern
1709     * @throws IllegalStateException if this scanner is closed
1710     * @throws IllegalArgumentException if horizon is negative
1711     */
1712    public String findWithinHorizon(Pattern pattern, int horizon) {
1713        ensureOpen();
1714        if (pattern == null)
1715            throw new NullPointerException();
1716        if (horizon < 0)
1717            throw new IllegalArgumentException("horizon < 0");
1718        clearCaches();
1719
1720        // Search for the pattern
1721        while (true) {
1722            String token = findPatternInBuffer(pattern, horizon);
1723            if (token != null) {
1724                matchValid = true;
1725                return token;
1726            }
1727            if (needInput)
1728                readInput();
1729            else
1730                break; // up to end of input
1731        }
1732        return null;
1733    }
1734
1735    /**
1736     * Skips input that matches the specified pattern, ignoring delimiters.
1737     * This method will skip input if an anchored match of the specified
1738     * pattern succeeds.
1739     *
1740     * <p>If a match to the specified pattern is not found at the
1741     * current position, then no input is skipped and a
1742     * <tt>NoSuchElementException</tt> is thrown.
1743     *
1744     * <p>Since this method seeks to match the specified pattern starting at
1745     * the scanner's current position, patterns that can match a lot of
1746     * input (".*", for example) may cause the scanner to buffer a large
1747     * amount of input.
1748     *
1749     * <p>Note that it is possible to skip something without risking a
1750     * <code>NoSuchElementException</code> by using a pattern that can
1751     * match nothing, e.g., <code>sc.skip("[ \t]*")</code>.
1752     *
1753     * @param pattern a string specifying the pattern to skip over
1754     * @return this scanner
1755     * @throws NoSuchElementException if the specified pattern is not found
1756     * @throws IllegalStateException if this scanner is closed
1757     */
1758    public Scanner skip(Pattern pattern) {
1759        ensureOpen();
1760        if (pattern == null)
1761            throw new NullPointerException();
1762        clearCaches();
1763
1764        // Search for the pattern
1765        while (true) {
1766            String token = matchPatternInBuffer(pattern);
1767            if (token != null) {
1768                matchValid = true;
1769                position = matcher.end();
1770                return this;
1771            }
1772            if (needInput)
1773                readInput();
1774            else
1775                throw new NoSuchElementException();
1776        }
1777    }
1778
1779    /**
1780     * Skips input that matches a pattern constructed from the specified
1781     * string.
1782     *
1783     * <p> An invocation of this method of the form <tt>skip(pattern)</tt>
1784     * behaves in exactly the same way as the invocation
1785     * <tt>skip(Pattern.compile(pattern))</tt>.
1786     *
1787     * @param pattern a string specifying the pattern to skip over
1788     * @return this scanner
1789     * @throws IllegalStateException if this scanner is closed
1790     */
1791    public Scanner skip(String pattern) {
1792        return skip(patternCache.forName(pattern));
1793    }
1794
1795    // Convenience methods for scanning primitives
1796
1797    /**
1798     * Returns true if the next token in this scanner's input can be
1799     * interpreted as a boolean value using a case insensitive pattern
1800     * created from the string "true|false".  The scanner does not
1801     * advance past the input that matched.
1802     *
1803     * @return true if and only if this scanner's next token is a valid
1804     *         boolean value
1805     * @throws IllegalStateException if this scanner is closed
1806     */
1807    public boolean hasNextBoolean()  {
1808        return hasNext(boolPattern());
1809    }
1810
1811    /**
1812     * Scans the next token of the input into a boolean value and returns
1813     * that value. This method will throw <code>InputMismatchException</code>
1814     * if the next token cannot be translated into a valid boolean value.
1815     * If the match is successful, the scanner advances past the input that
1816     * matched.
1817     *
1818     * @return the boolean scanned from the input
1819     * @throws InputMismatchException if the next token is not a valid boolean
1820     * @throws NoSuchElementException if input is exhausted
1821     * @throws IllegalStateException if this scanner is closed
1822     */
1823    public boolean nextBoolean()  {
1824        clearCaches();
1825        return Boolean.parseBoolean(next(boolPattern()));
1826    }
1827
1828    /**
1829     * Returns true if the next token in this scanner's input can be
1830     * interpreted as a byte value in the default radix using the
1831     * {@link #nextByte} method. The scanner does not advance past any input.
1832     *
1833     * @return true if and only if this scanner's next token is a valid
1834     *         byte value
1835     * @throws IllegalStateException if this scanner is closed
1836     */
1837    public boolean hasNextByte() {
1838        return hasNextByte(defaultRadix);
1839    }
1840
1841    /**
1842     * Returns true if the next token in this scanner's input can be
1843     * interpreted as a byte value in the specified radix using the
1844     * {@link #nextByte} method. The scanner does not advance past any input.
1845     *
1846     * @param radix the radix used to interpret the token as a byte value
1847     * @return true if and only if this scanner's next token is a valid
1848     *         byte value
1849     * @throws IllegalStateException if this scanner is closed
1850     */
1851    public boolean hasNextByte(int radix) {
1852        setRadix(radix);
1853        boolean result = hasNext(integerPattern());
1854        if (result) { // Cache it
1855            try {
1856                String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
1857                    processIntegerToken(hasNextResult) :
1858                    hasNextResult;
1859                typeCache = Byte.parseByte(s, radix);
1860            } catch (NumberFormatException nfe) {
1861                result = false;
1862            }
1863        }
1864        return result;
1865    }
1866
1867    /**
1868     * Scans the next token of the input as a <tt>byte</tt>.
1869     *
1870     * <p> An invocation of this method of the form
1871     * <tt>nextByte()</tt> behaves in exactly the same way as the
1872     * invocation <tt>nextByte(radix)</tt>, where <code>radix</code>
1873     * is the default radix of this scanner.
1874     *
1875     * @return the <tt>byte</tt> scanned from the input
1876     * @throws InputMismatchException
1877     *         if the next token does not match the <i>Integer</i>
1878     *         regular expression, or is out of range
1879     * @throws NoSuchElementException if input is exhausted
1880     * @throws IllegalStateException if this scanner is closed
1881     */
1882    public byte nextByte() {
1883         return nextByte(defaultRadix);
1884    }
1885
1886    /**
1887     * Scans the next token of the input as a <tt>byte</tt>.
1888     * This method will throw <code>InputMismatchException</code>
1889     * if the next token cannot be translated into a valid byte value as
1890     * described below. If the translation is successful, the scanner advances
1891     * past the input that matched.
1892     *
1893     * <p> If the next token matches the <a
1894     * href="#Integer-regex"><i>Integer</i></a> regular expression defined
1895     * above then the token is converted into a <tt>byte</tt> value as if by
1896     * removing all locale specific prefixes, group separators, and locale
1897     * specific suffixes, then mapping non-ASCII digits into ASCII
1898     * digits via {@link Character#digit Character.digit}, prepending a
1899     * negative sign (-) if the locale specific negative prefixes and suffixes
1900     * were present, and passing the resulting string to
1901     * {@link Byte#parseByte(String, int) Byte.parseByte} with the
1902     * specified radix.
1903     *
1904     * @param radix the radix used to interpret the token as a byte value
1905     * @return the <tt>byte</tt> scanned from the input
1906     * @throws InputMismatchException
1907     *         if the next token does not match the <i>Integer</i>
1908     *         regular expression, or is out of range
1909     * @throws NoSuchElementException if input is exhausted
1910     * @throws IllegalStateException if this scanner is closed
1911     */
1912    public byte nextByte(int radix) {
1913        // Check cached result
1914        if ((typeCache != null) && (typeCache instanceof Byte)
1915            && this.radix == radix) {
1916            byte val = ((Byte)typeCache).byteValue();
1917            useTypeCache();
1918            return val;
1919        }
1920        setRadix(radix);
1921        clearCaches();
1922        // Search for next byte
1923        try {
1924            String s = next(integerPattern());
1925            if (matcher.group(SIMPLE_GROUP_INDEX) == null)
1926                s = processIntegerToken(s);
1927            return Byte.parseByte(s, radix);
1928        } catch (NumberFormatException nfe) {
1929            position = matcher.start(); // don't skip bad token
1930            throw new InputMismatchException(nfe.getMessage());
1931        }
1932    }
1933
1934    /**
1935     * Returns true if the next token in this scanner's input can be
1936     * interpreted as a short value in the default radix using the
1937     * {@link #nextShort} method. The scanner does not advance past any input.
1938     *
1939     * @return true if and only if this scanner's next token is a valid
1940     *         short value in the default radix
1941     * @throws IllegalStateException if this scanner is closed
1942     */
1943    public boolean hasNextShort() {
1944        return hasNextShort(defaultRadix);
1945    }
1946
1947    /**
1948     * Returns true if the next token in this scanner's input can be
1949     * interpreted as a short value in the specified radix using the
1950     * {@link #nextShort} method. The scanner does not advance past any input.
1951     *
1952     * @param radix the radix used to interpret the token as a short value
1953     * @return true if and only if this scanner's next token is a valid
1954     *         short value in the specified radix
1955     * @throws IllegalStateException if this scanner is closed
1956     */
1957    public boolean hasNextShort(int radix) {
1958        setRadix(radix);
1959        boolean result = hasNext(integerPattern());
1960        if (result) { // Cache it
1961            try {
1962                String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
1963                    processIntegerToken(hasNextResult) :
1964                    hasNextResult;
1965                typeCache = Short.parseShort(s, radix);
1966            } catch (NumberFormatException nfe) {
1967                result = false;
1968            }
1969        }
1970        return result;
1971    }
1972
1973    /**
1974     * Scans the next token of the input as a <tt>short</tt>.
1975     *
1976     * <p> An invocation of this method of the form
1977     * <tt>nextShort()</tt> behaves in exactly the same way as the
1978     * invocation <tt>nextShort(radix)</tt>, where <code>radix</code>
1979     * is the default radix of this scanner.
1980     *
1981     * @return the <tt>short</tt> scanned from the input
1982     * @throws InputMismatchException
1983     *         if the next token does not match the <i>Integer</i>
1984     *         regular expression, or is out of range
1985     * @throws NoSuchElementException if input is exhausted
1986     * @throws IllegalStateException if this scanner is closed
1987     */
1988    public short nextShort() {
1989        return nextShort(defaultRadix);
1990    }
1991
1992    /**
1993     * Scans the next token of the input as a <tt>short</tt>.
1994     * This method will throw <code>InputMismatchException</code>
1995     * if the next token cannot be translated into a valid short value as
1996     * described below. If the translation is successful, the scanner advances
1997     * past the input that matched.
1998     *
1999     * <p> If the next token matches the <a
2000     * href="#Integer-regex"><i>Integer</i></a> regular expression defined
2001     * above then the token is converted into a <tt>short</tt> value as if by
2002     * removing all locale specific prefixes, group separators, and locale
2003     * specific suffixes, then mapping non-ASCII digits into ASCII
2004     * digits via {@link Character#digit Character.digit}, prepending a
2005     * negative sign (-) if the locale specific negative prefixes and suffixes
2006     * were present, and passing the resulting string to
2007     * {@link Short#parseShort(String, int) Short.parseShort} with the
2008     * specified radix.
2009     *
2010     * @param radix the radix used to interpret the token as a short value
2011     * @return the <tt>short</tt> scanned from the input
2012     * @throws InputMismatchException
2013     *         if the next token does not match the <i>Integer</i>
2014     *         regular expression, or is out of range
2015     * @throws NoSuchElementException if input is exhausted
2016     * @throws IllegalStateException if this scanner is closed
2017     */
2018    public short nextShort(int radix) {
2019        // Check cached result
2020        if ((typeCache != null) && (typeCache instanceof Short)
2021            && this.radix == radix) {
2022            short val = ((Short)typeCache).shortValue();
2023            useTypeCache();
2024            return val;
2025        }
2026        setRadix(radix);
2027        clearCaches();
2028        // Search for next short
2029        try {
2030            String s = next(integerPattern());
2031            if (matcher.group(SIMPLE_GROUP_INDEX) == null)
2032                s = processIntegerToken(s);
2033            return Short.parseShort(s, radix);
2034        } catch (NumberFormatException nfe) {
2035            position = matcher.start(); // don't skip bad token
2036            throw new InputMismatchException(nfe.getMessage());
2037        }
2038    }
2039
2040    /**
2041     * Returns true if the next token in this scanner's input can be
2042     * interpreted as an int value in the default radix using the
2043     * {@link #nextInt} method. The scanner does not advance past any input.
2044     *
2045     * @return true if and only if this scanner's next token is a valid
2046     *         int value
2047     * @throws IllegalStateException if this scanner is closed
2048     */
2049    public boolean hasNextInt() {
2050        return hasNextInt(defaultRadix);
2051    }
2052
2053    /**
2054     * Returns true if the next token in this scanner's input can be
2055     * interpreted as an int value in the specified radix using the
2056     * {@link #nextInt} method. The scanner does not advance past any input.
2057     *
2058     * @param radix the radix used to interpret the token as an int value
2059     * @return true if and only if this scanner's next token is a valid
2060     *         int value
2061     * @throws IllegalStateException if this scanner is closed
2062     */
2063    public boolean hasNextInt(int radix) {
2064        setRadix(radix);
2065        boolean result = hasNext(integerPattern());
2066        if (result) { // Cache it
2067            try {
2068                String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
2069                    processIntegerToken(hasNextResult) :
2070                    hasNextResult;
2071                typeCache = Integer.parseInt(s, radix);
2072            } catch (NumberFormatException nfe) {
2073                result = false;
2074            }
2075        }
2076        return result;
2077    }
2078
2079    /**
2080     * The integer token must be stripped of prefixes, group separators,
2081     * and suffixes, non ascii digits must be converted into ascii digits
2082     * before parse will accept it.
2083     */
2084    private String processIntegerToken(String token) {
2085        String result = token.replaceAll(""+groupSeparator, "");
2086        boolean isNegative = false;
2087        int preLen = negativePrefix.length();
2088        if ((preLen > 0) && result.startsWith(negativePrefix)) {
2089            isNegative = true;
2090            result = result.substring(preLen);
2091        }
2092        int sufLen = negativeSuffix.length();
2093        if ((sufLen > 0) && result.endsWith(negativeSuffix)) {
2094            isNegative = true;
2095            result = result.substring(result.length() - sufLen,
2096                                      result.length());
2097        }
2098        if (isNegative)
2099            result = "-" + result;
2100        return result;
2101    }
2102
2103    /**
2104     * Scans the next token of the input as an <tt>int</tt>.
2105     *
2106     * <p> An invocation of this method of the form
2107     * <tt>nextInt()</tt> behaves in exactly the same way as the
2108     * invocation <tt>nextInt(radix)</tt>, where <code>radix</code>
2109     * is the default radix of this scanner.
2110     *
2111     * @return the <tt>int</tt> scanned from the input
2112     * @throws InputMismatchException
2113     *         if the next token does not match the <i>Integer</i>
2114     *         regular expression, or is out of range
2115     * @throws NoSuchElementException if input is exhausted
2116     * @throws IllegalStateException if this scanner is closed
2117     */
2118    public int nextInt() {
2119        return nextInt(defaultRadix);
2120    }
2121
2122    /**
2123     * Scans the next token of the input as an <tt>int</tt>.
2124     * This method will throw <code>InputMismatchException</code>
2125     * if the next token cannot be translated into a valid int value as
2126     * described below. If the translation is successful, the scanner advances
2127     * past the input that matched.
2128     *
2129     * <p> If the next token matches the <a
2130     * href="#Integer-regex"><i>Integer</i></a> regular expression defined
2131     * above then the token is converted into an <tt>int</tt> value as if by
2132     * removing all locale specific prefixes, group separators, and locale
2133     * specific suffixes, then mapping non-ASCII digits into ASCII
2134     * digits via {@link Character#digit Character.digit}, prepending a
2135     * negative sign (-) if the locale specific negative prefixes and suffixes
2136     * were present, and passing the resulting string to
2137     * {@link Integer#parseInt(String, int) Integer.parseInt} with the
2138     * specified radix.
2139     *
2140     * @param radix the radix used to interpret the token as an int value
2141     * @return the <tt>int</tt> scanned from the input
2142     * @throws InputMismatchException
2143     *         if the next token does not match the <i>Integer</i>
2144     *         regular expression, or is out of range
2145     * @throws NoSuchElementException if input is exhausted
2146     * @throws IllegalStateException if this scanner is closed
2147     */
2148    public int nextInt(int radix) {
2149        // Check cached result
2150        if ((typeCache != null) && (typeCache instanceof Integer)
2151            && this.radix == radix) {
2152            int val = ((Integer)typeCache).intValue();
2153            useTypeCache();
2154            return val;
2155        }
2156        setRadix(radix);
2157        clearCaches();
2158        // Search for next int
2159        try {
2160            String s = next(integerPattern());
2161            if (matcher.group(SIMPLE_GROUP_INDEX) == null)
2162                s = processIntegerToken(s);
2163            return Integer.parseInt(s, radix);
2164        } catch (NumberFormatException nfe) {
2165            position = matcher.start(); // don't skip bad token
2166            throw new InputMismatchException(nfe.getMessage());
2167        }
2168    }
2169
2170    /**
2171     * Returns true if the next token in this scanner's input can be
2172     * interpreted as a long value in the default radix using the
2173     * {@link #nextLong} method. The scanner does not advance past any input.
2174     *
2175     * @return true if and only if this scanner's next token is a valid
2176     *         long value
2177     * @throws IllegalStateException if this scanner is closed
2178     */
2179    public boolean hasNextLong() {
2180        return hasNextLong(defaultRadix);
2181    }
2182
2183    /**
2184     * Returns true if the next token in this scanner's input can be
2185     * interpreted as a long value in the specified radix using the
2186     * {@link #nextLong} method. The scanner does not advance past any input.
2187     *
2188     * @param radix the radix used to interpret the token as a long value
2189     * @return true if and only if this scanner's next token is a valid
2190     *         long value
2191     * @throws IllegalStateException if this scanner is closed
2192     */
2193    public boolean hasNextLong(int radix) {
2194        setRadix(radix);
2195        boolean result = hasNext(integerPattern());
2196        if (result) { // Cache it
2197            try {
2198                String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
2199                    processIntegerToken(hasNextResult) :
2200                    hasNextResult;
2201                typeCache = Long.parseLong(s, radix);
2202            } catch (NumberFormatException nfe) {
2203                result = false;
2204            }
2205        }
2206        return result;
2207    }
2208
2209    /**
2210     * Scans the next token of the input as a <tt>long</tt>.
2211     *
2212     * <p> An invocation of this method of the form
2213     * <tt>nextLong()</tt> behaves in exactly the same way as the
2214     * invocation <tt>nextLong(radix)</tt>, where <code>radix</code>
2215     * is the default radix of this scanner.
2216     *
2217     * @return the <tt>long</tt> scanned from the input
2218     * @throws InputMismatchException
2219     *         if the next token does not match the <i>Integer</i>
2220     *         regular expression, or is out of range
2221     * @throws NoSuchElementException if input is exhausted
2222     * @throws IllegalStateException if this scanner is closed
2223     */
2224    public long nextLong() {
2225        return nextLong(defaultRadix);
2226    }
2227
2228    /**
2229     * Scans the next token of the input as a <tt>long</tt>.
2230     * This method will throw <code>InputMismatchException</code>
2231     * if the next token cannot be translated into a valid long value as
2232     * described below. If the translation is successful, the scanner advances
2233     * past the input that matched.
2234     *
2235     * <p> If the next token matches the <a
2236     * href="#Integer-regex"><i>Integer</i></a> regular expression defined
2237     * above then the token is converted into a <tt>long</tt> value as if by
2238     * removing all locale specific prefixes, group separators, and locale
2239     * specific suffixes, then mapping non-ASCII digits into ASCII
2240     * digits via {@link Character#digit Character.digit}, prepending a
2241     * negative sign (-) if the locale specific negative prefixes and suffixes
2242     * were present, and passing the resulting string to
2243     * {@link Long#parseLong(String, int) Long.parseLong} with the
2244     * specified radix.
2245     *
2246     * @param radix the radix used to interpret the token as an int value
2247     * @return the <tt>long</tt> scanned from the input
2248     * @throws InputMismatchException
2249     *         if the next token does not match the <i>Integer</i>
2250     *         regular expression, or is out of range
2251     * @throws NoSuchElementException if input is exhausted
2252     * @throws IllegalStateException if this scanner is closed
2253     */
2254    public long nextLong(int radix) {
2255        // Check cached result
2256        if ((typeCache != null) && (typeCache instanceof Long)
2257            && this.radix == radix) {
2258            long val = ((Long)typeCache).longValue();
2259            useTypeCache();
2260            return val;
2261        }
2262        setRadix(radix);
2263        clearCaches();
2264        try {
2265            String s = next(integerPattern());
2266            if (matcher.group(SIMPLE_GROUP_INDEX) == null)
2267                s = processIntegerToken(s);
2268            return Long.parseLong(s, radix);
2269        } catch (NumberFormatException nfe) {
2270            position = matcher.start(); // don't skip bad token
2271            throw new InputMismatchException(nfe.getMessage());
2272        }
2273    }
2274
2275    /**
2276     * The float token must be stripped of prefixes, group separators,
2277     * and suffixes, non ascii digits must be converted into ascii digits
2278     * before parseFloat will accept it.
2279     *
2280     * If there are non-ascii digits in the token these digits must
2281     * be processed before the token is passed to parseFloat.
2282     */
2283    private String processFloatToken(String token) {
2284        String result = token.replaceAll(groupSeparator, "");
2285        if (!decimalSeparator.equals("\\."))
2286            result = result.replaceAll(decimalSeparator, ".");
2287        boolean isNegative = false;
2288        int preLen = negativePrefix.length();
2289        if ((preLen > 0) && result.startsWith(negativePrefix)) {
2290            isNegative = true;
2291            result = result.substring(preLen);
2292        }
2293        int sufLen = negativeSuffix.length();
2294        if ((sufLen > 0) && result.endsWith(negativeSuffix)) {
2295            isNegative = true;
2296            result = result.substring(result.length() - sufLen,
2297                                      result.length());
2298        }
2299        if (result.equals(nanString))
2300            result = "NaN";
2301        if (result.equals(infinityString))
2302            result = "Infinity";
2303        if (isNegative)
2304            result = "-" + result;
2305
2306        // Translate non-ASCII digits
2307        Matcher m = NON_ASCII_DIGIT.matcher(result);
2308        if (m.find()) {
2309            StringBuilder inASCII = new StringBuilder();
2310            for (int i=0; i<result.length(); i++) {
2311                char nextChar = result.charAt(i);
2312                if (Character.isDigit(nextChar)) {
2313                    int d = Character.digit(nextChar, 10);
2314                    if (d != -1)
2315                        inASCII.append(d);
2316                    else
2317                        inASCII.append(nextChar);
2318                } else {
2319                    inASCII.append(nextChar);
2320                }
2321            }
2322            result = inASCII.toString();
2323        }
2324
2325        return result;
2326    }
2327
2328    /**
2329     * Returns true if the next token in this scanner's input can be
2330     * interpreted as a float value using the {@link #nextFloat}
2331     * method. The scanner does not advance past any input.
2332     *
2333     * @return true if and only if this scanner's next token is a valid
2334     *         float value
2335     * @throws IllegalStateException if this scanner is closed
2336     */
2337    public boolean hasNextFloat() {
2338        setRadix(10);
2339        boolean result = hasNext(floatPattern());
2340        if (result) { // Cache it
2341            try {
2342                String s = processFloatToken(hasNextResult);
2343                typeCache = Float.valueOf(Float.parseFloat(s));
2344            } catch (NumberFormatException nfe) {
2345                result = false;
2346            }
2347        }
2348        return result;
2349    }
2350
2351    /**
2352     * Scans the next token of the input as a <tt>float</tt>.
2353     * This method will throw <code>InputMismatchException</code>
2354     * if the next token cannot be translated into a valid float value as
2355     * described below. If the translation is successful, the scanner advances
2356     * past the input that matched.
2357     *
2358     * <p> If the next token matches the <a
2359     * href="#Float-regex"><i>Float</i></a> regular expression defined above
2360     * then the token is converted into a <tt>float</tt> value as if by
2361     * removing all locale specific prefixes, group separators, and locale
2362     * specific suffixes, then mapping non-ASCII digits into ASCII
2363     * digits via {@link Character#digit Character.digit}, prepending a
2364     * negative sign (-) if the locale specific negative prefixes and suffixes
2365     * were present, and passing the resulting string to
2366     * {@link Float#parseFloat Float.parseFloat}. If the token matches
2367     * the localized NaN or infinity strings, then either "Nan" or "Infinity"
2368     * is passed to {@link Float#parseFloat(String) Float.parseFloat} as
2369     * appropriate.
2370     *
2371     * @return the <tt>float</tt> scanned from the input
2372     * @throws InputMismatchException
2373     *         if the next token does not match the <i>Float</i>
2374     *         regular expression, or is out of range
2375     * @throws NoSuchElementException if input is exhausted
2376     * @throws IllegalStateException if this scanner is closed
2377     */
2378    public float nextFloat() {
2379        // Check cached result
2380        if ((typeCache != null) && (typeCache instanceof Float)) {
2381            float val = ((Float)typeCache).floatValue();
2382            useTypeCache();
2383            return val;
2384        }
2385        setRadix(10);
2386        clearCaches();
2387        try {
2388            return Float.parseFloat(processFloatToken(next(floatPattern())));
2389        } catch (NumberFormatException nfe) {
2390            position = matcher.start(); // don't skip bad token
2391            throw new InputMismatchException(nfe.getMessage());
2392        }
2393    }
2394
2395    /**
2396     * Returns true if the next token in this scanner's input can be
2397     * interpreted as a double value using the {@link #nextDouble}
2398     * method. The scanner does not advance past any input.
2399     *
2400     * @return true if and only if this scanner's next token is a valid
2401     *         double value
2402     * @throws IllegalStateException if this scanner is closed
2403     */
2404    public boolean hasNextDouble() {
2405        setRadix(10);
2406        boolean result = hasNext(floatPattern());
2407        if (result) { // Cache it
2408            try {
2409                String s = processFloatToken(hasNextResult);
2410                typeCache = Double.valueOf(Double.parseDouble(s));
2411            } catch (NumberFormatException nfe) {
2412                result = false;
2413            }
2414        }
2415        return result;
2416    }
2417
2418    /**
2419     * Scans the next token of the input as a <tt>double</tt>.
2420     * This method will throw <code>InputMismatchException</code>
2421     * if the next token cannot be translated into a valid double value.
2422     * If the translation is successful, the scanner advances past the input
2423     * that matched.
2424     *
2425     * <p> If the next token matches the <a
2426     * href="#Float-regex"><i>Float</i></a> regular expression defined above
2427     * then the token is converted into a <tt>double</tt> value as if by
2428     * removing all locale specific prefixes, group separators, and locale
2429     * specific suffixes, then mapping non-ASCII digits into ASCII
2430     * digits via {@link Character#digit Character.digit}, prepending a
2431     * negative sign (-) if the locale specific negative prefixes and suffixes
2432     * were present, and passing the resulting string to
2433     * {@link Double#parseDouble Double.parseDouble}. If the token matches
2434     * the localized NaN or infinity strings, then either "Nan" or "Infinity"
2435     * is passed to {@link Double#parseDouble(String) Double.parseDouble} as
2436     * appropriate.
2437     *
2438     * @return the <tt>double</tt> scanned from the input
2439     * @throws InputMismatchException
2440     *         if the next token does not match the <i>Float</i>
2441     *         regular expression, or is out of range
2442     * @throws NoSuchElementException if the input is exhausted
2443     * @throws IllegalStateException if this scanner is closed
2444     */
2445    public double nextDouble() {
2446        // Check cached result
2447        if ((typeCache != null) && (typeCache instanceof Double)) {
2448            double val = ((Double)typeCache).doubleValue();
2449            useTypeCache();
2450            return val;
2451        }
2452        setRadix(10);
2453        clearCaches();
2454        // Search for next float
2455        try {
2456            return Double.parseDouble(processFloatToken(next(floatPattern())));
2457        } catch (NumberFormatException nfe) {
2458            position = matcher.start(); // don't skip bad token
2459            throw new InputMismatchException(nfe.getMessage());
2460        }
2461    }
2462
2463    // Convenience methods for scanning multi precision numbers
2464
2465    /**
2466     * Returns true if the next token in this scanner's input can be
2467     * interpreted as a <code>BigInteger</code> in the default radix using the
2468     * {@link #nextBigInteger} method. The scanner does not advance past any
2469     * input.
2470     *
2471     * @return true if and only if this scanner's next token is a valid
2472     *         <code>BigInteger</code>
2473     * @throws IllegalStateException if this scanner is closed
2474     */
2475    public boolean hasNextBigInteger() {
2476        return hasNextBigInteger(defaultRadix);
2477    }
2478
2479    /**
2480     * Returns true if the next token in this scanner's input can be
2481     * interpreted as a <code>BigInteger</code> in the specified radix using
2482     * the {@link #nextBigInteger} method. The scanner does not advance past
2483     * any input.
2484     *
2485     * @param radix the radix used to interpret the token as an integer
2486     * @return true if and only if this scanner's next token is a valid
2487     *         <code>BigInteger</code>
2488     * @throws IllegalStateException if this scanner is closed
2489     */
2490    public boolean hasNextBigInteger(int radix) {
2491        setRadix(radix);
2492        boolean result = hasNext(integerPattern());
2493        if (result) { // Cache it
2494            try {
2495                String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
2496                    processIntegerToken(hasNextResult) :
2497                    hasNextResult;
2498                typeCache = new BigInteger(s, radix);
2499            } catch (NumberFormatException nfe) {
2500                result = false;
2501            }
2502        }
2503        return result;
2504    }
2505
2506    /**
2507     * Scans the next token of the input as a {@link java.math.BigInteger
2508     * BigInteger}.
2509     *
2510     * <p> An invocation of this method of the form
2511     * <tt>nextBigInteger()</tt> behaves in exactly the same way as the
2512     * invocation <tt>nextBigInteger(radix)</tt>, where <code>radix</code>
2513     * is the default radix of this scanner.
2514     *
2515     * @return the <tt>BigInteger</tt> scanned from the input
2516     * @throws InputMismatchException
2517     *         if the next token does not match the <i>Integer</i>
2518     *         regular expression, or is out of range
2519     * @throws NoSuchElementException if the input is exhausted
2520     * @throws IllegalStateException if this scanner is closed
2521     */
2522    public BigInteger nextBigInteger() {
2523        return nextBigInteger(defaultRadix);
2524    }
2525
2526    /**
2527     * Scans the next token of the input as a {@link java.math.BigInteger
2528     * BigInteger}.
2529     *
2530     * <p> If the next token matches the <a
2531     * href="#Integer-regex"><i>Integer</i></a> regular expression defined
2532     * above then the token is converted into a <tt>BigInteger</tt> value as if
2533     * by removing all group separators, mapping non-ASCII digits into ASCII
2534     * digits via the {@link Character#digit Character.digit}, and passing the
2535     * resulting string to the {@link
2536     * java.math.BigInteger#BigInteger(java.lang.String)
2537     * BigInteger(String, int)} constructor with the specified radix.
2538     *
2539     * @param radix the radix used to interpret the token
2540     * @return the <tt>BigInteger</tt> scanned from the input
2541     * @throws InputMismatchException
2542     *         if the next token does not match the <i>Integer</i>
2543     *         regular expression, or is out of range
2544     * @throws NoSuchElementException if the input is exhausted
2545     * @throws IllegalStateException if this scanner is closed
2546     */
2547    public BigInteger nextBigInteger(int radix) {
2548        // Check cached result
2549        if ((typeCache != null) && (typeCache instanceof BigInteger)
2550            && this.radix == radix) {
2551            BigInteger val = (BigInteger)typeCache;
2552            useTypeCache();
2553            return val;
2554        }
2555        setRadix(radix);
2556        clearCaches();
2557        // Search for next int
2558        try {
2559            String s = next(integerPattern());
2560            if (matcher.group(SIMPLE_GROUP_INDEX) == null)
2561                s = processIntegerToken(s);
2562            return new BigInteger(s, radix);
2563        } catch (NumberFormatException nfe) {
2564            position = matcher.start(); // don't skip bad token
2565            throw new InputMismatchException(nfe.getMessage());
2566        }
2567    }
2568
2569    /**
2570     * Returns true if the next token in this scanner's input can be
2571     * interpreted as a <code>BigDecimal</code> using the
2572     * {@link #nextBigDecimal} method. The scanner does not advance past any
2573     * input.
2574     *
2575     * @return true if and only if this scanner's next token is a valid
2576     *         <code>BigDecimal</code>
2577     * @throws IllegalStateException if this scanner is closed
2578     */
2579    public boolean hasNextBigDecimal() {
2580        setRadix(10);
2581        boolean result = hasNext(decimalPattern());
2582        if (result) { // Cache it
2583            try {
2584                String s = processFloatToken(hasNextResult);
2585                typeCache = new BigDecimal(s);
2586            } catch (NumberFormatException nfe) {
2587                result = false;
2588            }
2589        }
2590        return result;
2591    }
2592
2593    /**
2594     * Scans the next token of the input as a {@link java.math.BigDecimal
2595     * BigDecimal}.
2596     *
2597     * <p> If the next token matches the <a
2598     * href="#Decimal-regex"><i>Decimal</i></a> regular expression defined
2599     * above then the token is converted into a <tt>BigDecimal</tt> value as if
2600     * by removing all group separators, mapping non-ASCII digits into ASCII
2601     * digits via the {@link Character#digit Character.digit}, and passing the
2602     * resulting string to the {@link
2603     * java.math.BigDecimal#BigDecimal(java.lang.String) BigDecimal(String)}
2604     * constructor.
2605     *
2606     * @return the <tt>BigDecimal</tt> scanned from the input
2607     * @throws InputMismatchException
2608     *         if the next token does not match the <i>Decimal</i>
2609     *         regular expression, or is out of range
2610     * @throws NoSuchElementException if the input is exhausted
2611     * @throws IllegalStateException if this scanner is closed
2612     */
2613    public BigDecimal nextBigDecimal() {
2614        // Check cached result
2615        if ((typeCache != null) && (typeCache instanceof BigDecimal)) {
2616            BigDecimal val = (BigDecimal)typeCache;
2617            useTypeCache();
2618            return val;
2619        }
2620        setRadix(10);
2621        clearCaches();
2622        // Search for next float
2623        try {
2624            String s = processFloatToken(next(decimalPattern()));
2625            return new BigDecimal(s);
2626        } catch (NumberFormatException nfe) {
2627            position = matcher.start(); // don't skip bad token
2628            throw new InputMismatchException(nfe.getMessage());
2629        }
2630    }
2631
2632    /**
2633     * Resets this scanner.
2634     *
2635     * <p> Resetting a scanner discards all of its explicit state
2636     * information which may have been changed by invocations of {@link
2637     * #useDelimiter}, {@link #useLocale}, or {@link #useRadix}.
2638     *
2639     * <p> An invocation of this method of the form
2640     * <tt>scanner.reset()</tt> behaves in exactly the same way as the
2641     * invocation
2642     *
2643     * <blockquote><pre>
2644     *   scanner.useDelimiter("\\p{javaWhitespace}+")
2645     *          .useLocale(Locale.getDefault())
2646     *          .useRadix(10);
2647     * </pre></blockquote>
2648     *
2649     * @return this scanner
2650     *
2651     * @since 1.6
2652     */
2653    public Scanner reset() {
2654        delimPattern = WHITESPACE_PATTERN;
2655        useLocale(Locale.getDefault(Locale.Category.FORMAT));
2656        useRadix(10);
2657        clearCaches();
2658        return this;
2659    }
2660}
2661