import java.util.regex.Pattern;
import org.hedgecode.chess.ParseException;
+import org.hedgecode.chess.pgn.PGNUtils;
import org.hedgecode.chess.pgn.entity.Game;
+import static org.hedgecode.chess.pgn.PGNConstants.*;
+
/**
* Tokenizer
*
}
}
- private static final Pattern TAG_PATTERN = Pattern.compile("^\\[[^]]+\\]$", Pattern.MULTILINE);
- private static final Pattern EMPTY_PATTERN = Pattern.compile("^\\s*$", Pattern.MULTILINE);
- private static final Pattern MOVES_PATTERN = Pattern.compile("^\\s*([^\\s])", Pattern.MULTILINE);
+ private static final Pattern TAG_PATTERN = Pattern.compile("^\\[[^]]+\\]$");
+ private static final Pattern EMPTY_PATTERN = Pattern.compile("^\\s*$");
+ private static final Pattern MOVES_PATTERN = Pattern.compile("^\\s*[0-9{(;*]+");
- private final String pgn;
+ private final String originalPgn;
private Token<Game> token;
private String tokenPgn;
+ private boolean isTagExists = false;
+ private boolean isEmptyExists = false;
+ private boolean isMovesExists = false;
+
public Tokenizer(String pgn) {
- this.pgn = pgn;
- this.tokenPgn = pgn;
+ this.originalPgn = pgn;
+ this.tokenPgn = pgn.endsWith(PGN_CRLF) ? pgn : pgn.concat(PGN_CRLF);
}
public boolean hasToken() {
}
public void token(Game game) throws ParseException {
- if (token == null) {
- throw new ParseException("parse.pgn.null.token");
- }
+ assertToken();
int index = token.token(game, tokenPgn);
tokenPgn = tokenPgn.substring(index);
token = null;
}
- public String sourcePgn() {
- return pgn;
+ public String originalPgn() {
+ return originalPgn;
}
private void assignToken() {
token = null;
if (!tokenPgn.isEmpty()) {
- if (TAG_PATTERN.matcher(tokenPgn).find()) {
+ String pgnLine = PGNUtils.nextLine(tokenPgn);
+ if (TAG_PATTERN.matcher(pgnLine).find()) {
+ isTagExists = true;
token = Type.TAG.token();
- } else if (EMPTY_PATTERN.matcher(tokenPgn).find()) {
+ } else if (EMPTY_PATTERN.matcher(pgnLine).find()) {
+ isEmptyExists = true;
token = Type.EMPTY.token();
- } else if (MOVES_PATTERN.matcher(tokenPgn).find()) {
+ } else if (MOVES_PATTERN.matcher(pgnLine).find()) {
+ isMovesExists = true;
token = Type.MOVES.token();
}
}
}
+ private void assertToken() throws ParseException {
+ if (token == null) {
+ throw new ParseException("parse.pgn.null.token");
+ } else {
+ if (!isTagExists && (isEmptyExists || isMovesExists)) {
+ throw new ParseException("parse.pgn.tag.not.exist");
+ } else if (!isEmptyExists && isMovesExists) {
+ throw new ParseException("parse.pgn.missed.empty");
+ }
+ }
+ }
+
}