Scanners { public static Parser<Void> nestedScanner(final Parser<?> outer, final Parser<Void> inner) { return new Parser<Void>() { @Override boolean apply(ParseContext ctxt) { int from = ctxt.at; if (!outer.apply(ctxt)) return false; ScannerState innerState = new ScannerState( ctxt.module, ctxt.characters(), from, ctxt.at, ctxt.locator, ctxt.result); ctxt.getTrace().startFresh(innerState); innerState.getTrace().setStateAs(ctxt.getTrace()); return ctxt.applyNested(inner, innerState); } @Override public String toString() { return "nested scanner"; } }; } private  Scanners(); static Parser<Void> many(CharPredicate predicate); static Parser<Void> many1(CharPredicate predicate); @Deprecated static Parser<Void> many(Pattern pattern, String name); @Deprecated static Parser<Void> many1(Pattern pattern, String name); static Parser<Void> string(String str); @Deprecated static Parser<Void> string(String str, String name); @Deprecated static Parser<Void> pattern(final Pattern pattern, final String name); @Deprecated static Parser<Void> stringCaseInsensitive(String str, String name); static Parser<Void> stringCaseInsensitive(String str); static Parser<Void> isChar(final CharPredicate predicate); @Deprecated static Parser<Void> isChar(CharPredicate predicate, String name); @Deprecated static Parser<Void> isChar(char ch, String name); static Parser<Void> isChar(char ch); @Deprecated static Parser<Void> notChar(char ch, String name); static Parser<Void> notChar(char ch); @Deprecated static Parser<Void> among(String chars, String name); static Parser<Void> among(String chars); @Deprecated static Parser<Void> notAmong(String chars, String name); static Parser<Void> notAmong(String chars); static Parser<Void> lineComment(String begin); static Parser<Void> blockComment(String begin, String end); static Parser<Void> blockComment(String begin, String end, Pattern commented); static Parser<Void> blockComment(Parser<Void> begin, Parser<Void> end, Parser<?> commented); static Parser<Void> nestableBlockComment(String begin, String end); static Parser<Void> nestableBlockComment(String begin, String end, Pattern commented); static Parser<Void> nestableBlockComment(
      Parser<?> begin, Parser<?> end, Parser<?> commented); static Parser<String> quoted(char begin, char end); @Deprecated static Parser<String> quoted(Parser<Void> begin, Parser<Void> end, Parser<?> quoted); static Parser<Void> nestedScanner(final Parser<?> outer, final Parser<Void> inner); static final Parser<Void> WHITESPACES; static final Parser<Void> ANY_CHAR; static final Parser<Void> JAVA_LINE_COMMENT; static final Parser<Void> SQL_LINE_COMMENT; static final Parser<Void> HASKELL_LINE_COMMENT; static final Parser<Void> JAVA_BLOCK_COMMENT; static final Parser<Void> SQL_BLOCK_COMMENT; static final Parser<Void> HASKELL_BLOCK_COMMENT; static final Parser<String> SINGLE_QUOTE_STRING; static final Parser<String> DOUBLE_QUOTE_STRING; static final Parser<String> SINGLE_QUOTE_CHAR; static final Parser<Void> JAVA_DELIMITER; static final Parser<Void> HASKELL_DELIMITER; static final Parser<Void> SQL_DELIMITER; static final Parser<String> IDENTIFIER; static final Parser<String> INTEGER; static final Parser<String> DECIMAL; static final Parser<String> DEC_INTEGER; static final Parser<String> OCT_INTEGER; static final Parser<String> HEX_INTEGER; static final Parser<String> SCIENTIFIC_NOTATION; }
@Test public void testNestedScanner() { Parser<Void> scanner = Scanners.nestedScanner( Scanners.isChar(CharPredicates.IS_ALPHA).skipMany1(), Scanners.isChar('a').skipTimes(2)); assertEquals("nested scanner", scanner.toString()); assertNull(scanner.parse("aa")); assertNull(scanner.parse("aabb")); assertFailure(mode, scanner, "ab", 1, 2); assertFailure(mode, scanner, "01", 1, 1); assertNull(Scanners.isChar(' ').next(scanner).parse(" aa")); assertNull(Scanners.isChar(' ').next(scanner).parse(" aab")); assertScanner(mode, Scanners.isChar(' ').next(scanner), " aab1", "1"); assertScanner(mode, Scanners.isChar(' ').next(scanner), " aa1", "1"); }