package mireka.address.parser.base;
import java.text.ParseException;
import java.util.ArrayDeque;
import java.util.Deque;
public abstract class CharParser {
protected CharScanner scanner;
protected CharToken currentToken;
protected Spelling spelling = new Spelling();
private Deque<Integer> inputPositionStack = new ArrayDeque<Integer>();
protected CharParser(CharScanner charScanner) {
this.scanner = charScanner;
currentToken = charScanner.scan();
}
protected CharParser(String source) {
this(new CharScanner(source));
}
protected void accept(char ch) throws ParseException {
if (currentToken.ch == ch)
acceptIt();
else
throw currentToken.syntaxException(CharUtil.toVisibleChar(ch));
}
protected void accept(CharClass charClass) throws ParseException {
if (charClass.isSatisfiedBy(currentToken.ch))
acceptIt();
else
throw currentToken.syntaxException(charClass);
}
protected void acceptIt() {
spelling.appendChar(currentToken.ch);
currentToken = scanner.scan();
}
protected void acceptThem(int count) {
for (int i = 0; i < count; i++)
acceptIt();
}
protected String peekString(int length) {
if (length < 0)
throw new IllegalArgumentException("Length: " + length);
if (currentToken.ch == -1 || length == 0) {
return "";
} else {
StringBuilder buffer = new StringBuilder();
buffer.append((char) currentToken.ch);
if (length > 1)
buffer.append(scanner.peekString(length - 1));
return buffer.toString();
}
}
protected void pushSpelling() {
spelling.start();
}
protected String popSpelling() {
return spelling.finish();
}
/**
* Saves the current position within the input text onto a stack.
*/
protected void pushPosition() {
inputPositionStack.push(currentToken.position);
}
/**
* Returns and removes the last input text position which was put onto the
* stack using {@link #pushPosition()}.
*/
protected int popPosition() {
return inputPositionStack.pop();
}
}