mirror of
https://gitlab.com/manzerbredes/pgnp.git
synced 2025-04-05 17:46:25 +02:00
Improve parser
This commit is contained in:
parent
d4df0dac1d
commit
2e30eaccb1
5 changed files with 50 additions and 15 deletions
|
@ -63,4 +63,17 @@ void HalfMove::Copy(HalfMove *copy) {
|
|||
var->Copy(new_var);
|
||||
}
|
||||
}
|
||||
|
||||
HalfMove *HalfMove::GetHalfMoveAt(int distance) {
|
||||
HalfMove *tmp=this;
|
||||
while(distance>0){
|
||||
if(tmp==NULL){
|
||||
throw HalfMoveOutOfRange();
|
||||
}
|
||||
distance--;
|
||||
tmp=tmp->MainLine;
|
||||
}
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
} // namespace pgnp
|
|
@ -34,5 +34,11 @@ public:
|
|||
std::string Dump();
|
||||
/// @brief Perform a deep copy of a HalfMove
|
||||
void Copy(HalfMove *copy);
|
||||
/// @brief Get HalfMove located x down the MainLine
|
||||
HalfMove* GetHalfMoveAt(int);
|
||||
};
|
||||
|
||||
struct HalfMoveOutOfRange : public std::exception {
|
||||
const char *what() const throw() { return "HalfMove distance is out of range"; }
|
||||
};
|
||||
} // namespace pgnp
|
42
src/PGN.cpp
42
src/PGN.cpp
|
@ -33,7 +33,7 @@ void PGN::FromFile(std::string filepath) {
|
|||
|
||||
void PGN::FromString(std::string pgn_content) {
|
||||
this->pgn_content = pgn_content;
|
||||
moves = NULL;
|
||||
moves = new HalfMove();
|
||||
int loc = 0;
|
||||
while (!IS_EOF(loc)) {
|
||||
char c = pgn_content[loc];
|
||||
|
@ -41,9 +41,11 @@ void PGN::FromString(std::string pgn_content) {
|
|||
if (c == '[') {
|
||||
loc = ParseNextTag(loc);
|
||||
} else if (IS_DIGIT(c)) {
|
||||
moves = new HalfMove();
|
||||
loc = ParseHalfMove(loc, moves);
|
||||
break;
|
||||
} else if (c=='{') {
|
||||
loc = ParseComment(loc,moves);
|
||||
continue; // No need loc++
|
||||
}
|
||||
}
|
||||
loc++;
|
||||
|
@ -82,6 +84,27 @@ bool PGN::HasTag(std::string key) {
|
|||
return (std::find(tags.begin(), tags.end(), key) != tags.end());
|
||||
}
|
||||
|
||||
int PGN::ParseComment(int loc, HalfMove *hm) {
|
||||
// Goto next char
|
||||
loc = NextNonBlank(loc);
|
||||
EOF_CHECK(loc);
|
||||
char c = pgn_content[loc];
|
||||
|
||||
if(c=='{'){
|
||||
loc++;
|
||||
EOF_CHECK(loc);
|
||||
c = pgn_content[loc];
|
||||
while(c!='}'){
|
||||
hm->comment+=c;
|
||||
loc++;
|
||||
EOF_CHECK(loc);
|
||||
c = pgn_content[loc];
|
||||
}
|
||||
loc++; // Skip '}'
|
||||
}
|
||||
return(loc);
|
||||
}
|
||||
|
||||
int PGN::ParseHalfMove(int loc, HalfMove *hm) {
|
||||
// Goto next char
|
||||
loc = NextNonBlank(loc);
|
||||
|
@ -147,19 +170,8 @@ int PGN::ParseHalfMove(int loc, HalfMove *hm) {
|
|||
return (loc);
|
||||
}
|
||||
|
||||
// Check for comment
|
||||
loc = NextNonBlank(loc);
|
||||
if (!IS_EOF(loc) && pgn_content[loc] == '{') {
|
||||
loc++; // Skip '{'
|
||||
c = pgn_content[loc];
|
||||
while (c != '}') {
|
||||
hm->comment += c;
|
||||
loc++;
|
||||
EOF_CHECK(loc);
|
||||
c = pgn_content[loc];
|
||||
}
|
||||
loc++; // Skip '}'
|
||||
}
|
||||
// Parse comment
|
||||
loc=ParseComment(loc,hm);
|
||||
|
||||
// Check for variations
|
||||
loc = NextNonBlank(loc);
|
||||
|
|
|
@ -47,6 +47,7 @@ private:
|
|||
int NextNonBlank(int);
|
||||
/// @brief Parse a HalfMove at a specific location into @a pgn_content
|
||||
int ParseHalfMove(int, HalfMove *);
|
||||
int ParseComment(int,HalfMove *);
|
||||
};
|
||||
|
||||
struct UnexpectedEOF : public std::exception {
|
||||
|
|
|
@ -58,6 +58,7 @@ TEST_CASE("Valid PGN", "[valid/pgn1]") {
|
|||
CHECK_THROWS_AS(pgn.GetTagValue("InvalidTagName"), InvalidTagName);
|
||||
}
|
||||
|
||||
CHECK(m_backup->GetHalfMoveAt(4)->move == "c4");
|
||||
CHECK(pgn.GetResult() == "*");
|
||||
}
|
||||
|
||||
|
@ -69,6 +70,8 @@ TEST_CASE("Valid PGN", "[valid/pgn2]") {
|
|||
pgn.GetMoves(m);
|
||||
REQUIRE(m->GetLength() == 66);
|
||||
CHECK(pgn.GetResult() == "0-1");
|
||||
CHECK(m->comment == " A00 Hungarian Opening ");
|
||||
CHECK(m->GetHalfMoveAt(7)->comment == " (0.22 → 0.74) Inaccuracy. dxc4 was best. ");
|
||||
}
|
||||
|
||||
TEST_CASE("Seven Tag Roster", "[std/pgn1]") {
|
||||
|
|
Loading…
Add table
Reference in a new issue