From 39906bc01d13100a22bd6f4dcb42c8410ea6d99c Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Tue, 25 Nov 2025 13:42:31 +0100 Subject: [PATCH] - Treballant en el deserialitzador --- main.cpp | 17 ++++-- test.yaml | 1 + yamal.hpp | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 168 insertions(+), 5 deletions(-) diff --git a/main.cpp b/main.cpp index 986fba3..87c6b67 100644 --- a/main.cpp +++ b/main.cpp @@ -1,9 +1,20 @@ #include #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[]) { - yamal root; - root["room"]["name"] = "THE JAIL"; + yamal root = yamal_parser::parse(readFileToString("test.yaml")); + + /*root["room"]["name"] = "THE JAIL"; root["room"]["name"].setQuoted(true); root["room"]["bgColor"] = "bright_blue"; root["room"]["connections"]["up"] = "null"; @@ -40,7 +51,7 @@ int main(int argc, char* argv[]) { root["room"].setBlankLine(false); root["tilemap"].setComment("Tilemap: 16 filas x 32 columnas (256x192 píxeles @ 8px/tile)"); 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; return 0; diff --git a/test.yaml b/test.yaml index 708d0e4..333b84b 100644 --- a/test.yaml +++ b/test.yaml @@ -3,6 +3,7 @@ room: name: "THE JAIL" bgColor: bright_blue # Azul oscuro connections: + # peiv up: null down: null left: null diff --git a/yamal.hpp b/yamal.hpp index 9109bcc..3c1a1a3 100644 --- a/yamal.hpp +++ b/yamal.hpp @@ -5,6 +5,9 @@ #include #include #include +#include +#include +#include template class ordered_map { @@ -107,8 +110,12 @@ public: } // Inline comment accessors - const std::string& getInlineComment() const { return inline_comment; } - yamal& setInlineComment(const std::string& c) { inline_comment = c; return *this; } + const std::string& getInlineComment() const { + return inline_comment; + } + yamal& setInlineComment(const std::string& c) { + inline_comment = c; return *this; + } // Formatting yamal& setQuoted(bool q = true) { quoted = q; return *this; } @@ -256,7 +263,151 @@ public: 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: + 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) { std::ostringstream out; std::istringstream in(c);