- Treballant en el deserialitzador

This commit is contained in:
2025-11-25 13:42:31 +01:00
parent d727a88aa7
commit 39906bc01d
3 changed files with 168 additions and 5 deletions

View File

@@ -1,9 +1,20 @@
#include <iostream> #include <iostream>
#include "yamal.hpp" #include "yamal.hpp"
std::string readFileToString(const std::string& filename) {
std::ifstream ifs(filename);
if (!ifs) {
throw std::runtime_error("Cannot open file: " + filename);
}
std::ostringstream oss;
oss << ifs.rdbuf(); // dump the whole stream buffer into oss
return oss.str();
}
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
yamal root; yamal root = yamal_parser::parse(readFileToString("test.yaml"));
root["room"]["name"] = "THE JAIL";
/*root["room"]["name"] = "THE JAIL";
root["room"]["name"].setQuoted(true); root["room"]["name"].setQuoted(true);
root["room"]["bgColor"] = "bright_blue"; root["room"]["bgColor"] = "bright_blue";
root["room"]["connections"]["up"] = "null"; root["room"]["connections"]["up"] = "null";
@@ -40,7 +51,7 @@ int main(int argc, char* argv[]) {
root["room"].setBlankLine(false); root["room"].setBlankLine(false);
root["tilemap"].setComment("Tilemap: 16 filas x 32 columnas (256x192 píxeles @ 8px/tile)"); root["tilemap"].setComment("Tilemap: 16 filas x 32 columnas (256x192 píxeles @ 8px/tile)");
root["tilemap"].appendComment("Índices de tiles (-1 = vacío)"); root["tilemap"].appendComment("Índices de tiles (-1 = vacío)");
root["room"]["bgColor"].setInlineComment("Azul oscuro"); root["room"]["bgColor"].setInlineComment("Azul oscuro");*/
std::cout << root.serialize() << std::endl; std::cout << root.serialize() << std::endl;
return 0; return 0;

View File

@@ -3,6 +3,7 @@ room:
name: "THE JAIL" name: "THE JAIL"
bgColor: bright_blue # Azul oscuro bgColor: bright_blue # Azul oscuro
connections: connections:
# peiv
up: null up: null
down: null down: null
left: null left: null

155
yamal.hpp
View File

@@ -5,6 +5,9 @@
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
#include <cctype> #include <cctype>
#include <fstream>
#include <iostream>
#include <string.h>
template<typename Value> template<typename Value>
class ordered_map { class ordered_map {
@@ -107,8 +110,12 @@ public:
} }
// Inline comment accessors // Inline comment accessors
const std::string& getInlineComment() const { return inline_comment; } const std::string& getInlineComment() const {
yamal& setInlineComment(const std::string& c) { inline_comment = c; return *this; } return inline_comment;
}
yamal& setInlineComment(const std::string& c) {
inline_comment = c; return *this;
}
// Formatting // Formatting
yamal& setQuoted(bool q = true) { quoted = q; return *this; } yamal& setQuoted(bool q = true) { quoted = q; return *this; }
@@ -256,7 +263,151 @@ public:
return out.str(); return out.str();
} }
void deserialize(std::string buffer) {
tokenizer::init(buffer);
deserialize(-1);
}
void deserialize(int indent) {
if (tokenizer::error()) return;
int current_indent = -2;
tokenizer::getNextToken();
while(tokenizer::type != tokenizer::types::ENDOFFILE) {
switch (tokenizer::type) {
case tokenizer::types::COMMENT:
tokenizer::getNextToken();
// Ignore for now
break;
case tokenizer::types::BLANKLINE:
tokenizer::getNextToken();
// Ignore for now
break;
case tokenizer::types::KEY:
if (tokenizer::indent <= indent) return;
if (current_indent<0) current_indent = tokenizer::indent;
if (tokenizer::indent != current_indent) tokenizer::error("Wrong indent");
(*this)[tokenizer::string].serialize();
break;
case tokenizer::types::SCALAR:
}
}
}
private: private:
class tokenizer
{
public:
enum class types { COMMENT, BLANKLINE, KEY, SCALAR, VECTOR, INLINEVEC, COMMA, INLINEVECOFF,
INLINEKEY, INLINEKEYOFF, ENDOFFILE };
static types type;
static int indent;
static std::string string;
static const char *buffer;
static int line;
static int col;
static bool inlined;
static bool error_state;
static void init(std::string buffer) {
tokenizer::buffer = buffer.c_str();
col = line = 0;
inlined = false;
error_state = false;
}
static bool error() { return error_state; }
static void error(std::string message) {
error_state = true;
printf("YAML ERROR: %s at line %i col %i\n", message.c_str(), line, col);
}
static char next() {
if (*buffer==0) return *buffer;
if (*buffer==13) buffer++;
if (*buffer==10) { col=0; line++; } else { col++; }
return *(buffer++);
}
static void ignoreWhiteSpace() { while (strchr(" \t", *buffer)) next(); }
static void getEverythingUntilEOL() {
char tmp[256]; int i=0;
while (*buffer!=10 && *buffer!=13 && *buffer!=0) tmp[i++]=next();
if (*buffer==13) next(); next(); tmp[i]=0; string = tmp;
}
static void getEverythingUntilQuote() {
char tmp[256]; int i=0;
while (*buffer!='"' && *buffer!=0) tmp[i++]=next();
next(); tmp[i]=0; string = tmp;
}
static types getWord() {
char tmp[256]; int i=0;
while (!strchr(" \t\r\n[]{}-#",*buffer)) tmp[i++]=next();
if (tmp[i-1]==':') { tmp[i-1]=0; string=tmp; return types::KEY;}
else { tmp[i]=0; string = tmp;; return types::SCALAR; }
}
static void getNextToken()
{
ignoreWhiteSpace();
indent = col;
switch (*buffer) {
case 0: {
type = types::ENDOFFILE;
break;
}
case '#': {
getEverythingUntilEOL();
type = types::COMMENT;
break;
}
case '"': {
getEverythingUntilQuote();
type = types::SCALAR;
break;
}
case '\r':
case '\n': {
type = types::BLANKLINE;
if (*buffer==13) next(); next();
break;
}
case '-': {
type = types::VECTOR;
next();
break;
}
case '[': {
type = types::INLINEVEC; inlined = true;
next();
break;
}
case ']': {
type = types::INLINEVECOFF; inlined = false;
next();
break;
}
case '{': {
type = types::INLINEKEY; inlined = true;
next();
break;
}
case '}': {
type = types::INLINEKEYOFF; inlined = false;
next();
break;
}
case ',': {
type = types::COMMA;
next();
break;
}
default: {
type = getWord();
break;
}
}
}
};
static std::string formatComment(const std::string& c, int indent) { static std::string formatComment(const std::string& c, int indent) {
std::ostringstream out; std::ostringstream out;
std::istringstream in(c); std::istringstream in(c);