package com.googlecode.totallylazy.parser;
import com.googlecode.totallylazy.Segment;
import com.googlecode.totallylazy.Strings;
import com.googlecode.totallylazy.regex.Regex;
import java.util.NoSuchElementException;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.googlecode.totallylazy.parser.CharacterSequence.charSequence;
import static com.googlecode.totallylazy.parser.Success.success;
class PatternParser implements Parser<String> {
private final Pattern pattern;
private PatternParser(Pattern pattern) {
this.pattern = pattern;
}
static PatternParser pattern(Pattern pattern) {
return new PatternParser(pattern);
}
static PatternParser pattern(String pattern) {
return pattern(Pattern.compile(pattern));
}
@Override
public String toString() {
return pattern.toString();
}
@Override
public Result<String> parse(Segment<Character> characters) {
CharacterSequence sequence = charSequence(characters);
Matcher matcher = pattern.matcher(sequence);
if (matches(matcher)) return success(matcher.group(), drop(matcher.end(), characters));
return fail(toString(), sequence);
}
private boolean matches(Matcher matcher) {
try {
return matcher.lookingAt();
} catch (NoSuchElementException e) {
return false;
}
}
private static <T> Segment<T> drop(int count, Segment<T> segment) {
Segment<T> current = segment;
for (int i = 0; i < count; i++) {
if(current.isEmpty()) return current;
current = current.tail();
}
return current;
}
}