From 6096fb9c48c80ad72f9677cc5261f2824f936775 Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Tue, 25 Nov 2025 19:09:18 +0100 Subject: [PATCH] - Ja funciona el deserialitzador, nomes falta que pille linies en blanc i comentaris --- main.cpp | 3 +- yamal.hpp | 121 +++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 100 insertions(+), 24 deletions(-) diff --git a/main.cpp b/main.cpp index 87c6b67..e0f4989 100644 --- a/main.cpp +++ b/main.cpp @@ -12,7 +12,8 @@ std::string readFileToString(const std::string& filename) { } int main(int argc, char* argv[]) { - yamal root = yamal_parser::parse(readFileToString("test.yaml")); + yamal root; // = yamal_parser::parse(readFileToString("test.yaml")); + root.deserialize(readFileToString("data/room/02.yaml")); /*root["room"]["name"] = "THE JAIL"; root["room"]["name"].setQuoted(true); diff --git a/yamal.hpp b/yamal.hpp index 3c1a1a3..14ca263 100644 --- a/yamal.hpp +++ b/yamal.hpp @@ -127,6 +127,10 @@ public: clearToVector(); vec_data.push_back(item); } + yamal& emplace_back() { + clearToVector(); + return vec_data.emplace_back(); + } yamal& operator[](size_t i) { clearToVector(); if (vec_data.size() <= i) vec_data.resize(i+1); @@ -285,11 +289,59 @@ public: 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(); + if (tokenizer::indent != current_indent) { tokenizer::error("Wrong indent"); return; } + (*this)[tokenizer::string].deserialize(current_indent); break; + case tokenizer::types::STRINGSCALAR: + this->setQuoted(true); case tokenizer::types::SCALAR: - + *(this) = tokenizer::string; + tokenizer::getNextToken(); + return; + case tokenizer::types::VECTOR: + if (tokenizer::indent <= indent) return; + if (current_indent<0) current_indent = tokenizer::indent; + if (tokenizer::indent != current_indent) { tokenizer::error("Wrong indent"); return; } + (*this).emplace_back().deserialize(current_indent); + break; + case tokenizer::types::INLINEVEC: { + (*this).setInline(true); + (*this).clearToVector(); + tokenizer::getNextToken(); + if (tokenizer::type == tokenizer::types::INLINEVECOFF) return; + while (tokenizer::type != tokenizer::types::ENDOFFILE) { + if (tokenizer::type != tokenizer::types::SCALAR && tokenizer::type != tokenizer::types::STRINGSCALAR) { tokenizer::error("Scalar expected"); return; } + (*this).emplace_back() = tokenizer::string; + tokenizer::getNextToken(); + if (tokenizer::type == tokenizer::types::INLINEVECOFF) return; + if (tokenizer::type != tokenizer::types::COMMA) { tokenizer::error("Comma expected"); return; } + tokenizer::getNextToken(); + } + tokenizer::error("Unexpected end of file"); return; + break; + } + case tokenizer::types::INLINEKEY: { + (*this).setInline(true); + (*this).clearToMap(); + tokenizer::getNextToken(); + if (tokenizer::type == tokenizer::types::INLINEKEYOFF) return; + while (tokenizer::type != tokenizer::types::ENDOFFILE) { + if (tokenizer::type != tokenizer::types::KEY) { tokenizer::error("Key expected"); return; } + std::string key = tokenizer::string; + tokenizer::getNextToken(); + if (tokenizer::type != tokenizer::types::SCALAR && tokenizer::type != tokenizer::types::STRINGSCALAR) { tokenizer::error("Scalar expected"); return; } + (*this)[key] = tokenizer::string; + tokenizer::getNextToken(); + if (tokenizer::type == tokenizer::types::INLINEKEYOFF) return; + if (tokenizer::type != tokenizer::types::COMMA) { tokenizer::error("Comma expected"); return; } + tokenizer::getNextToken(); + } + tokenizer::error("Unexpected end of file"); return; + break; + } + default: + tokenizer::getNextToken(); + } } } @@ -298,21 +350,23 @@ private: class tokenizer { public: - enum class types { COMMENT, BLANKLINE, KEY, SCALAR, VECTOR, INLINEVEC, COMMA, INLINEVECOFF, + enum class types { COMMENT, BLANKLINE, KEY, SCALAR, STRINGSCALAR, VECTOR, INLINEVEC, COMMA, INLINEVECOFF, INLINEKEY, INLINEKEYOFF, ENDOFFILE }; - static types type; - static int indent; - static std::string string; + inline static types type; + inline static int indent; + inline static std::string string; - static const char *buffer; - static int line; - static int col; - static bool inlined; + inline static std::string buffer_string; + inline static const char *buffer; + inline static int line; + inline static int col; + inline static bool inlined; - static bool error_state; + inline static bool error_state; - static void init(std::string buffer) { - tokenizer::buffer = buffer.c_str(); + static void init(std::string file) { + buffer_string = file; + buffer = buffer_string.c_str(); col = line = 0; inlined = false; error_state = false; @@ -320,7 +374,7 @@ private: 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); + printf("YAML ERROR: %s at line %i col %i\n", message.c_str(), line+1, col+1); } static char next() { if (*buffer==0) return *buffer; @@ -328,22 +382,29 @@ private: if (*buffer==10) { col=0; line++; } else { col++; } return *(buffer++); } - static void ignoreWhiteSpace() { while (strchr(" \t", *buffer)) next(); } + static void ignoreWhiteSpace() { while (*buffer==32 || *buffer==9) 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; + char tmp[256]; int i=0; next(); 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; } + const char *delimiters = inlined ? " \t\r\n[]{}#," : " \t\r\n[]{}#"; + while (!strchr(delimiters,*buffer)) tmp[i++]=next(); + if (tmp[i-1]==':') { + printf("KEY at line %i col %i\n", line, indent); + tmp[i-1]=0; string=tmp; return types::KEY; + } + else { + printf("SCALAR at line %i col %i\n", line, indent); + tmp[i]=0; string = tmp;; return types::SCALAR; + } } static void getNextToken() { @@ -351,51 +412,65 @@ private: indent = col; switch (*buffer) { case 0: { + printf("ENDOFFILE at line %i col %i\n", line, indent); type = types::ENDOFFILE; break; } case '#': { + printf("COMMENT at line %i col %i\n", line, indent); getEverythingUntilEOL(); type = types::COMMENT; break; } case '"': { + printf("STRING SCALAR at line %i col %i\n", line, indent); getEverythingUntilQuote(); - type = types::SCALAR; + type = types::STRINGSCALAR; break; } case '\r': case '\n': { + printf("BLANKLINE at line %i col %i\n", line, indent); type = types::BLANKLINE; if (*buffer==13) next(); next(); break; } case '-': { - type = types::VECTOR; - next(); + if (*(buffer+1)==' ') { + printf("VECTOR at line %i col %i\n", line, indent); + type = types::VECTOR; + next(); + } else { + type = getWord(); + } break; } case '[': { + printf("INLINEVEC at line %i col %i\n", line, indent); type = types::INLINEVEC; inlined = true; next(); break; } case ']': { + printf("INLINEVECOFF at line %i col %i\n", line, indent); type = types::INLINEVECOFF; inlined = false; next(); break; } case '{': { + printf("INLINEKEY at line %i col %i\n", line, indent); type = types::INLINEKEY; inlined = true; next(); break; } case '}': { + printf("INLINEKEYOFF at line %i col %i\n", line, indent); type = types::INLINEKEYOFF; inlined = false; next(); break; } case ',': { + printf("COMMA at line %i col %i\n", line, indent); type = types::COMMA; next(); break;