/** * Returns a parser that produces the given stream of characters or fails otherwise. * * @param missing The error if the producing stream could not supply more characters. * @param sat The error if a character was produced that is not the given stream of characters. * @param cs The stream of characters to produce. * @return A parser that produces the given stream of characters or fails otherwise. */ public static <E> Parser<Stream<Character>, Stream<Character>, E> characters( final F0<E> missing, final F<Character, E> sat, final Stream<Character> cs) { return cs.isEmpty() ? Parser.<Stream<Character>, Stream<Character>, E>value(Stream.<Character>nil()) : character(missing, sat, cs.head()) .bind(characters(missing, sat, cs.tail()._1()), Stream.<Character>cons_()); }
/** * Returns a parser that produces an element from the stream that satisfies the given predicate, * or fails. * * @param missing The error if no element is available. * @param sat The error if the element does not satisfy the predicate. * @param f The predicate that the element should satisfy. * @return A parser that produces an element from the stream that satisfies the given predicate, * or fails. */ public static <I, E> Parser<Stream<I>, I, E> satisfy( final F0<E> missing, final F<I, E> sat, final F<I, Boolean> f) { return StreamParser.<I, E>element(missing) .bind( x -> f.f(x) ? Parser.<Stream<I>, I, E>value(x) : Parser.<Stream<I>, I, E>fail(sat.f(x))); }
/** * Returns a parser that produces the given number of characters, or fails with the given error. * * @param missing The error if the given number of characters is unavailable. * @param n The number of characters to produce in the parse result. * @return A parser that produces the given number of characters, or fails with the given error. */ public static <E> Parser<Stream<Character>, Stream<Character>, E> characters( final F0<E> missing, final int n) { return n <= 0 ? Parser.<Stream<Character>, Stream<Character>, E>value(Stream.<Character>nil()) : character(missing).bind(characters(missing, n - 1), Stream.<Character>cons_()); }
/** * Sequence the list of parsers through {@link #bind}. * * @param ps The parsers to sequence. * @return A parser after sequencing. */ public static <I, A, E> Parser<I, List<A>, E> sequence(final List<Parser<I, A, E>> ps) { return ps.isEmpty() ? Parser.<I, List<A>, E>value(List.<A>nil()) : ps.head().bind(a -> sequence(ps.tail()).map(cons_(a))); }