package mireka.address.parser;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import mireka.address.parser.ast.DomainAST;
import mireka.address.parser.ast.MailboxAST;
import mireka.address.parser.ast.PathAST;
import mireka.address.parser.ast.SourceRouteAST;
import mireka.address.parser.base.CharParser;
import mireka.address.parser.base.CharScanner;
public class PathParser extends CharParser {
public PathParser(String source) {
this(new CharScanner(source));
}
public PathParser(CharScanner charScanner) {
super(charScanner);
}
public PathAST parse() throws ParseException {
PathAST pathAST = parsePath();
if (currentToken.ch != -1)
throw currentToken.otherSyntaxException("Superfluous characters "
+ "after path: {0}.");
return pathAST;
}
public PathAST parseLeft() throws ParseException {
PathAST pathAST = parsePath();
scanner.pushBack(currentToken);
return pathAST;
}
private PathAST parsePath() throws ParseException {
pushPosition();
SourceRouteAST sourceRouteAST = null;
accept('<');
if (currentToken.ch == '@') {
sourceRouteAST = parseSourceRoute();
accept(':');
}
MailboxAST mailboxAST = parseMailbox();
accept('>');
return new PathAST(popPosition(), sourceRouteAST, mailboxAST);
}
private SourceRouteAST parseSourceRoute() throws ParseException {
pushPosition();
List<DomainAST> domainASTs = new ArrayList<DomainAST>();
do {
accept('@');
DomainAST domainAST = parseDomain();
domainASTs.add(domainAST);
} while (currentToken.ch == '@');
return new SourceRouteAST(popPosition(), domainASTs);
}
private DomainAST parseDomain() throws ParseException {
scanner.pushBack(currentToken);
DomainAST domainAST = new DomainParser(scanner).parseLeft();
spelling.append(domainAST.spelling);
currentToken = scanner.scan();
return domainAST;
}
private MailboxAST parseMailbox() throws ParseException {
scanner.pushBack(currentToken);
MailboxAST mailboxAST = new MailboxParser(scanner).parseLeft();
currentToken = scanner.scan();
return mailboxAST;
}
}