- Ja funciona el deserialitzador, nomes falta que pille linies en blanc i comentaris

This commit is contained in:
2025-11-25 19:09:18 +01:00
parent 39906bc01d
commit 6096fb9c48
2 changed files with 100 additions and 24 deletions

View File

@@ -12,7 +12,8 @@ std::string readFileToString(const std::string& filename) {
} }
int main(int argc, char* argv[]) { 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"] = "THE JAIL";
root["room"]["name"].setQuoted(true); root["room"]["name"].setQuoted(true);

115
yamal.hpp
View File

@@ -127,6 +127,10 @@ public:
clearToVector(); clearToVector();
vec_data.push_back(item); vec_data.push_back(item);
} }
yamal& emplace_back() {
clearToVector();
return vec_data.emplace_back();
}
yamal& operator[](size_t i) { yamal& operator[](size_t i) {
clearToVector(); clearToVector();
if (vec_data.size() <= i) vec_data.resize(i+1); if (vec_data.size() <= i) vec_data.resize(i+1);
@@ -285,10 +289,58 @@ public:
case tokenizer::types::KEY: case tokenizer::types::KEY:
if (tokenizer::indent <= indent) return; if (tokenizer::indent <= indent) return;
if (current_indent<0) current_indent = tokenizer::indent; if (current_indent<0) current_indent = tokenizer::indent;
if (tokenizer::indent != current_indent) tokenizer::error("Wrong indent"); if (tokenizer::indent != current_indent) { tokenizer::error("Wrong indent"); return; }
(*this)[tokenizer::string].serialize(); (*this)[tokenizer::string].deserialize(current_indent);
break; break;
case tokenizer::types::STRINGSCALAR:
this->setQuoted(true);
case tokenizer::types::SCALAR: 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 class tokenizer
{ {
public: 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 }; INLINEKEY, INLINEKEYOFF, ENDOFFILE };
static types type; inline static types type;
static int indent; inline static int indent;
static std::string string; inline static std::string string;
static const char *buffer; inline static std::string buffer_string;
static int line; inline static const char *buffer;
static int col; inline static int line;
static bool inlined; inline static int col;
inline static bool inlined;
static bool error_state; inline static bool error_state;
static void init(std::string buffer) { static void init(std::string file) {
tokenizer::buffer = buffer.c_str(); buffer_string = file;
buffer = buffer_string.c_str();
col = line = 0; col = line = 0;
inlined = false; inlined = false;
error_state = false; error_state = false;
@@ -320,7 +374,7 @@ private:
static bool error() { return error_state; } static bool error() { return error_state; }
static void error(std::string message) { static void error(std::string message) {
error_state = true; 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() { static char next() {
if (*buffer==0) return *buffer; if (*buffer==0) return *buffer;
@@ -328,22 +382,29 @@ private:
if (*buffer==10) { col=0; line++; } else { col++; } if (*buffer==10) { col=0; line++; } else { col++; }
return *(buffer++); return *(buffer++);
} }
static void ignoreWhiteSpace() { while (strchr(" \t", *buffer)) next(); } static void ignoreWhiteSpace() { while (*buffer==32 || *buffer==9) next(); }
static void getEverythingUntilEOL() { static void getEverythingUntilEOL() {
char tmp[256]; int i=0; char tmp[256]; int i=0;
while (*buffer!=10 && *buffer!=13 && *buffer!=0) tmp[i++]=next(); while (*buffer!=10 && *buffer!=13 && *buffer!=0) tmp[i++]=next();
if (*buffer==13) next(); next(); tmp[i]=0; string = tmp; if (*buffer==13) next(); next(); tmp[i]=0; string = tmp;
} }
static void getEverythingUntilQuote() { static void getEverythingUntilQuote() {
char tmp[256]; int i=0; char tmp[256]; int i=0; next();
while (*buffer!='"' && *buffer!=0) tmp[i++]=next(); while (*buffer!='"' && *buffer!=0) tmp[i++]=next();
next(); tmp[i]=0; string = tmp; next(); tmp[i]=0; string = tmp;
} }
static types getWord() { static types getWord() {
char tmp[256]; int i=0; char tmp[256]; int i=0;
while (!strchr(" \t\r\n[]{}-#",*buffer)) tmp[i++]=next(); const char *delimiters = inlined ? " \t\r\n[]{}#," : " \t\r\n[]{}#";
if (tmp[i-1]==':') { tmp[i-1]=0; string=tmp; return types::KEY;} while (!strchr(delimiters,*buffer)) tmp[i++]=next();
else { tmp[i]=0; string = tmp;; return types::SCALAR; } 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() static void getNextToken()
{ {
@@ -351,51 +412,65 @@ private:
indent = col; indent = col;
switch (*buffer) { switch (*buffer) {
case 0: { case 0: {
printf("ENDOFFILE at line %i col %i\n", line, indent);
type = types::ENDOFFILE; type = types::ENDOFFILE;
break; break;
} }
case '#': { case '#': {
printf("COMMENT at line %i col %i\n", line, indent);
getEverythingUntilEOL(); getEverythingUntilEOL();
type = types::COMMENT; type = types::COMMENT;
break; break;
} }
case '"': { case '"': {
printf("STRING SCALAR at line %i col %i\n", line, indent);
getEverythingUntilQuote(); getEverythingUntilQuote();
type = types::SCALAR; type = types::STRINGSCALAR;
break; break;
} }
case '\r': case '\r':
case '\n': { case '\n': {
printf("BLANKLINE at line %i col %i\n", line, indent);
type = types::BLANKLINE; type = types::BLANKLINE;
if (*buffer==13) next(); next(); if (*buffer==13) next(); next();
break; break;
} }
case '-': { case '-': {
if (*(buffer+1)==' ') {
printf("VECTOR at line %i col %i\n", line, indent);
type = types::VECTOR; type = types::VECTOR;
next(); next();
} else {
type = getWord();
}
break; break;
} }
case '[': { case '[': {
printf("INLINEVEC at line %i col %i\n", line, indent);
type = types::INLINEVEC; inlined = true; type = types::INLINEVEC; inlined = true;
next(); next();
break; break;
} }
case ']': { case ']': {
printf("INLINEVECOFF at line %i col %i\n", line, indent);
type = types::INLINEVECOFF; inlined = false; type = types::INLINEVECOFF; inlined = false;
next(); next();
break; break;
} }
case '{': { case '{': {
printf("INLINEKEY at line %i col %i\n", line, indent);
type = types::INLINEKEY; inlined = true; type = types::INLINEKEY; inlined = true;
next(); next();
break; break;
} }
case '}': { case '}': {
printf("INLINEKEYOFF at line %i col %i\n", line, indent);
type = types::INLINEKEYOFF; inlined = false; type = types::INLINEKEYOFF; inlined = false;
next(); next();
break; break;
} }
case ',': { case ',': {
printf("COMMA at line %i col %i\n", line, indent);
type = types::COMMA; type = types::COMMA;
next(); next();
break; break;