package com.googlecode.totallylazy.parser; import com.googlecode.totallylazy.functions.Callables; import com.googlecode.totallylazy.Segment; import com.googlecode.totallylazy.Sequence; import com.googlecode.totallylazy.Unchecked; import com.googlecode.totallylazy.iterators.StatefulIterator; import java.util.concurrent.atomic.AtomicReference; import static com.googlecode.totallylazy.Sequences.forwardOnly; class SequenceParser<A> implements Parser<Sequence<A>> { private final Parser<A> parser; private SequenceParser(Parser<A> parser) { this.parser = parser; } static <A> SequenceParser<A> sequence(Parser<A> parser) { return new SequenceParser<A>(Unchecked.<Parser<A>>cast(parser)); } public Result<Sequence<A>> parse(final Segment<Character> characters) { final AtomicReference<Segment<Character>> remainder = new AtomicReference<Segment<Character>>(characters); final StatefulIterator<Result<A>> iterator = new StatefulIterator<Result<A>>() { @Override protected Result<A> getNext() throws Exception { Result<A> result = parser.parse(remainder.get()); if (result.failure()) return finished(); remainder.set(result.remainder()); return result; } }; return new Success<Sequence<A>>() { @Override public Sequence<A> value() { return forwardOnly(iterator).map(Callables.<A>value()); } @Override public Segment<Character> remainder() { return remainder.get(); } }; } @Override public String toString() { return String.format("sequence %s", parser); } }