mirror of
https://gitlab.com/manzerbredes/pgnp.git
synced 2025-04-06 10:06: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);
|
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
|
} // namespace pgnp
|
|
@ -34,5 +34,11 @@ public:
|
||||||
std::string Dump();
|
std::string Dump();
|
||||||
/// @brief Perform a deep copy of a HalfMove
|
/// @brief Perform a deep copy of a HalfMove
|
||||||
void Copy(HalfMove *copy);
|
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
|
} // 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) {
|
void PGN::FromString(std::string pgn_content) {
|
||||||
this->pgn_content = pgn_content;
|
this->pgn_content = pgn_content;
|
||||||
moves = NULL;
|
moves = new HalfMove();
|
||||||
int loc = 0;
|
int loc = 0;
|
||||||
while (!IS_EOF(loc)) {
|
while (!IS_EOF(loc)) {
|
||||||
char c = pgn_content[loc];
|
char c = pgn_content[loc];
|
||||||
|
@ -41,9 +41,11 @@ void PGN::FromString(std::string pgn_content) {
|
||||||
if (c == '[') {
|
if (c == '[') {
|
||||||
loc = ParseNextTag(loc);
|
loc = ParseNextTag(loc);
|
||||||
} else if (IS_DIGIT(c)) {
|
} else if (IS_DIGIT(c)) {
|
||||||
moves = new HalfMove();
|
|
||||||
loc = ParseHalfMove(loc, moves);
|
loc = ParseHalfMove(loc, moves);
|
||||||
break;
|
break;
|
||||||
|
} else if (c=='{') {
|
||||||
|
loc = ParseComment(loc,moves);
|
||||||
|
continue; // No need loc++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loc++;
|
loc++;
|
||||||
|
@ -82,6 +84,27 @@ bool PGN::HasTag(std::string key) {
|
||||||
return (std::find(tags.begin(), tags.end(), key) != tags.end());
|
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) {
|
int PGN::ParseHalfMove(int loc, HalfMove *hm) {
|
||||||
// Goto next char
|
// Goto next char
|
||||||
loc = NextNonBlank(loc);
|
loc = NextNonBlank(loc);
|
||||||
|
@ -147,19 +170,8 @@ int PGN::ParseHalfMove(int loc, HalfMove *hm) {
|
||||||
return (loc);
|
return (loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for comment
|
// Parse comment
|
||||||
loc = NextNonBlank(loc);
|
loc=ParseComment(loc,hm);
|
||||||
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 '}'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for variations
|
// Check for variations
|
||||||
loc = NextNonBlank(loc);
|
loc = NextNonBlank(loc);
|
||||||
|
|
|
@ -47,6 +47,7 @@ private:
|
||||||
int NextNonBlank(int);
|
int NextNonBlank(int);
|
||||||
/// @brief Parse a HalfMove at a specific location into @a pgn_content
|
/// @brief Parse a HalfMove at a specific location into @a pgn_content
|
||||||
int ParseHalfMove(int, HalfMove *);
|
int ParseHalfMove(int, HalfMove *);
|
||||||
|
int ParseComment(int,HalfMove *);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UnexpectedEOF : public std::exception {
|
struct UnexpectedEOF : public std::exception {
|
||||||
|
|
|
@ -58,6 +58,7 @@ TEST_CASE("Valid PGN", "[valid/pgn1]") {
|
||||||
CHECK_THROWS_AS(pgn.GetTagValue("InvalidTagName"), InvalidTagName);
|
CHECK_THROWS_AS(pgn.GetTagValue("InvalidTagName"), InvalidTagName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CHECK(m_backup->GetHalfMoveAt(4)->move == "c4");
|
||||||
CHECK(pgn.GetResult() == "*");
|
CHECK(pgn.GetResult() == "*");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +70,8 @@ TEST_CASE("Valid PGN", "[valid/pgn2]") {
|
||||||
pgn.GetMoves(m);
|
pgn.GetMoves(m);
|
||||||
REQUIRE(m->GetLength() == 66);
|
REQUIRE(m->GetLength() == 66);
|
||||||
CHECK(pgn.GetResult() == "0-1");
|
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]") {
|
TEST_CASE("Seven Tag Roster", "[std/pgn1]") {
|
||||||
|
|
Loading…
Add table
Reference in a new issue