public PgnData() { coRegex = new Regex("^\\[([A-Za-z]*) \"(.*)\"", RegexOptions.Compiled); coValue = new System.Text.StringBuilder(); coState = GameParserState.State.HEADER; coPeriodCount = 0; }
/// <summary> /// Calls the correct event based on the parsers state. /// </summary> /// <param name="state"></param> void callEvent(GameParserState.State state) { if (coValue.Length > 0) { switch (state) { case GameParserState.State.COMMENT: if (EventCommentParsed != null) { EventCommentParsed(this); } break; case GameParserState.State.NAGS: if (EventNagParsed != null) { EventNagParsed(this); } break; case GameParserState.State.NUMBER: if (EventMoveParsed != null) { EventMoveParsed(this); } coState = GameParserState.State.COLOR; break; case GameParserState.State.WHITE: if (EventMoveParsed != null) { EventMoveParsed(this); } coState = GameParserState.State.BLACK; break; case GameParserState.State.BLACK: if (EventMoveParsed != null) { EventMoveParsed(this); } coState = GameParserState.State.NUMBER; break; } } // Always clear out our data as the handler should have used this value during the event. coValue.Length = 0; }
void handleChar(char aChar) { switch (aChar) { case '{': callEvent(coState); coPrevState = coState; coState = GameParserState.State.COMMENT; break; case '(': if (EventEnterVariation != null) { EventEnterVariation(this); } break; case ')': if (EventExitVariation != null) { EventExitVariation(this); } break; case ' ': // Only if we have some data do we want to fire an event. callEvent(coState); break; case '.': // We may have come across 6. e4 6... d5 as in our example data. coState = GameParserState.State.NUMBER; callEvent(coState); coPeriodCount = 1; break; case '$': callEvent(coState); coPrevState = coState; coState = GameParserState.State.NAGS; break; default: coValue.Append(aChar); break; } }
public void parse() { System.IO.StreamReader reader = new System.IO.StreamReader(coFilename); long position = 0; for (coData = reader.ReadLine(); coData != null; coData = reader.ReadLine()) { if (coData.Length > 0) { if (Regex.IsMatch(coData, "^\\[")) { if (coNextGame == false) { callEvent(coState); coNextGame = true; if (EventNewGame != null) { EventNewGame(this); } } coState = GameParserState.State.HEADER; parseTag(coData); coValue.Length = 0; } else { if (coNextGame) { coNextGame = false; } parseDetail(coData); } position += coData.Length + 2; } } callEvent(coState); reader.Close(); if (EventFinished != null) { EventFinished(this); } }
public void parseDetail(string line) { foreach (char aChar in line) { // Handle any special processing of our text. switch (coState) { case GameParserState.State.COMMENT: if (aChar == '}') { callEvent(coState); coState = coPrevState; } else { coValue.Append(aChar); } break; case GameParserState.State.NAGS: if (aChar >= '0' && aChar <= '9') { coValue.Append(aChar); } else { callEvent(coState); coState = coPrevState; handleChar(aChar); } break; case GameParserState.State.COLOR: if (aChar == '.') { coPeriodCount++; } else { coValue.Length = 0; if (coPeriodCount == 1) { coState = GameParserState.State.WHITE; } else if (coPeriodCount > 1) { coState = GameParserState.State.BLACK; } handleChar(aChar); coPeriodCount = 0; } break; default: handleChar(aChar); break; } } // Ensure we add a space between comment lines that are broken appart. if (coState == GameParserState.State.COMMENT) { coValue.Append(' '); } else { callEvent(coState); } }