From d9b66c8795c4470138be6d000e108779537d05d0 Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sun, 23 Jan 2022 13:50:12 +0300 Subject: [PATCH] feat: working subtables --- includes/TOMLParser.hpp | 4 +- includes/Tokenizer.hpp | 3 +- src/config/TOMLParser.cpp | 88 +++++++++++++++++++++++++++++++-------- src/config/Tokenizer.cpp | 21 +++++++--- 4 files changed, 90 insertions(+), 26 deletions(-) diff --git a/includes/TOMLParser.hpp b/includes/TOMLParser.hpp index 6cc5c8a..1be4c2a 100644 --- a/includes/TOMLParser.hpp +++ b/includes/TOMLParser.hpp @@ -16,16 +16,18 @@ namespace config TOMLMap *root; //root of TOML tree /* toml_node *current; //node currently being parsed */ Tokenizer tokenizer; + static std::vector split_name(std::string name); static void put_to_subtable(TOMLMap *root, std::vector full_name, - toml_node *map_node); + toml_node *map_node, toml_node::e_type type); public: TOMLParser(const std::string filename); TOMLMap *parse(void); toml_node *parseMap(void); + void processMap(void); void parseMapArray(void); diff --git a/includes/Tokenizer.hpp b/includes/Tokenizer.hpp index 2adb4ca..eec6321 100644 --- a/includes/Tokenizer.hpp +++ b/includes/Tokenizer.hpp @@ -26,8 +26,7 @@ namespace config NIL, OPEN_BRACKET, CLOSE_BRACKET, - MAP_OPEN, - MAP_CLOSE, + MAP_DECL, MAPARRAY_DECL }; diff --git a/src/config/TOMLParser.cpp b/src/config/TOMLParser.cpp index cdb7449..f77924b 100644 --- a/src/config/TOMLParser.cpp +++ b/src/config/TOMLParser.cpp @@ -28,6 +28,37 @@ namespace config TOMLParser::TOMLParser(const std::string filename) : tokenizer(filename) {}; + void TOMLParser::processMap(void) + { + std::cerr << "Processing map" << std::endl; + toml_node *map_node; + s_token current; + + try { current = tokenizer.getToken(); } + catch (std::logic_error e) + { + std::cerr << e.what() << std::endl; + return; + } + if (current.type == MAP_DECL) + { + if (tokenizer.getToken().type != NEWLINE) + throw std::logic_error("no newline after MAP_DECL"); + map_node = parseMap(); + } + else + throw std::logic_error("unexpected token in processMap"); + + std::cout << current.value << std::endl; + + std::vector full_name; + + full_name = split_name(current.value); + + put_to_subtable(root, full_name, map_node, toml_node::MAP); + + } + toml_node *TOMLParser::parseMap(void) { std::cerr << "Parsing map" << std::endl; @@ -51,9 +82,11 @@ namespace config tokenizer.set_last(NEWLINE); break; } - else if (nextToken.type == OPEN_BRACKET) + else if (nextToken.type == MAP_DECL) { - + tokenizer.rollBackToken(); + tokenizer.set_last(NEWLINE); + break; } std::string key = nextToken.value; std::cerr << key << std::endl; @@ -139,15 +172,13 @@ namespace config else throw std::logic_error("unexpected token in parseMapArray"); - TOMLMap::iterator it; std::cout << current.value << std::endl; - std::string name = current.value; + std::vector full_name; - full_name = split_name(name); + full_name = split_name(current.value); - /* throw std::logic_error("tha end"); */ - put_to_subtable(root, full_name, map_node); + put_to_subtable(root, full_name, map_node, toml_node::MAPARRAY); } @@ -294,6 +325,17 @@ namespace config tokenizer.rollBackToken(); parseMapArray(); } + else if (current.type == MAP_DECL) + { + std::cerr << "MAP_DECL value: " << current.value << std::endl; + tokenizer.set_last(NEWLINE); + tokenizer.rollBackToken(); + /* if (tokenizer.getToken().type != NEWLINE) */ + /* throw std::logic_error("no newline after MAP_DECL"); */ + /* (*mapObject)[nextToken.value] = parseMap(); */ + processMap(); + continue; + } else { std::string key = current.value; @@ -378,7 +420,7 @@ namespace config void TOMLParser::put_to_subtable(TOMLMap *root, std::vector full_name, - toml_node *map_node) + toml_node *map_node, toml_node::e_type type) { std::vector::iterator subname = full_name.begin(); toml_node *maparr_node; @@ -391,16 +433,28 @@ namespace config if (subname + 1 == full_name.end()) { it = local_root->find(*subname); - if (it == local_root->end()) + if (type == toml_node::MAPARRAY) { - maparr_node = new toml_node; - TOMLMapArray *map_array = new TOMLMapArray; - map_array->push_back(map_node->getMap()); - maparr_node->setMapArray(map_array); - (*local_root)[*subname] = maparr_node; + if (it == local_root->end()) + { + maparr_node = new toml_node; + TOMLMapArray *map_array = new TOMLMapArray; + map_array->push_back(map_node->getMap()); + maparr_node->setMapArray(map_array); + (*local_root)[*subname] = maparr_node; + } + else + (it->second)->getMapArray()->push_back(map_node->getMap()); + } + else if (type == toml_node::MAP) + { + if (it == local_root->end()) + { + (*local_root)[*subname] = map_node; + } + else + throw std::logic_error("map already in subtable!"); } - else - (it->second)->getMapArray()->push_back(map_node->getMap()); break; } else @@ -419,9 +473,7 @@ namespace config } /* subname found in local_root */ else - { local_root = *((it->second)->getMapArray()->end() - 1); - } } ++subname; diff --git a/src/config/Tokenizer.cpp b/src/config/Tokenizer.cpp index 5ad54ba..4d6f9c8 100644 --- a/src/config/Tokenizer.cpp +++ b/src/config/Tokenizer.cpp @@ -88,9 +88,9 @@ namespace config file.get(c); } } - else if (c == '[') + else if (c == '[' && firstToken()) { - std::streampos prev_pos = file.tellg(); + /* std::streampos prev_pos = file.tellg(); */ file.get(c); if (c == '[') { @@ -108,10 +108,21 @@ namespace config } else { - token.type = OPEN_BRACKET; - file.seekg(prev_pos); + token.type = MAP_DECL; + token.value += c; + file.get(c); + while (c != ']') + { + token.value += c; + file.get(c); + } + if (c != ']') + throw std::logic_error("malformed MAP_DECL"); } - + } + else if (c == '[') + { + token.type = OPEN_BRACKET; } else if (c == ']') token.type = CLOSE_BRACKET;