DelegatingScanner.java
package org.sterling.source.scanner;
import static java.util.Arrays.asList;
import static org.sterling.source.scanner.ScannerUtil.unexpectedInput;
import static org.sterling.source.syntax.NodeKind.ANYTHING;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.sterling.SterlingException;
import org.sterling.source.syntax.NodeKind;
import org.sterling.source.syntax.Token;
public class DelegatingScanner implements Scanner {
private final InputReader reader;
private final Map<NodeKind, ScannerDelegate> delegates;
public DelegatingScanner(InputReader reader, Map<NodeKind, ScannerDelegate> delegates) {
this.reader = reader;
this.delegates = new HashMap<>(delegates);
}
@Override
public void begin() {
reader.begin();
}
@Override
public void close() {
reader.close();
}
@Override
public void end() {
reader.end();
}
@Override
public boolean expect(NodeKind kind) {
if (delegates.containsKey(kind)) {
return delegates.get(kind).expect(kind, reader);
} else if (ANYTHING == kind) {
return true;
} else {
throw new IllegalArgumentException("No delegate registered to token kind " + kind);
}
}
@Override
public boolean expectOne(NodeKind... kinds) {
return expectOne(asList(kinds));
}
@Override
public boolean expectOne(Iterable<NodeKind> kinds) {
return ANYTHING != expected(kinds);
}
@Override
public NodeKind expected(Iterable<NodeKind> kinds) {
for (NodeKind kind : kinds) {
if (expect(kind)) {
return kind;
}
}
return ANYTHING;
}
@Override
public NodeKind expected(NodeKind... kinds) {
return expected(asList(kinds));
}
@Override
public Token require(NodeKind kind) throws SterlingException {
if (expect(kind)) {
return delegates.get(kind).require(kind, reader);
} else {
throw unexpectedInput(reader, kind);
}
}
@Override
public Token requireOne(NodeKind... kinds) throws SterlingException {
return requireOne(asList(kinds));
}
@Override
public Token requireOne(Collection<NodeKind> kinds) throws SterlingException {
for (NodeKind kind : kinds) {
if (expect(kind)) {
return require(kind);
}
}
throw unexpectedInput(reader, kinds);
}
@Override
public void restore() {
reader.rollback();
}
}