parent
							
								
									2ea548678b
								
							
						
					
					
						commit
						fc90bfb982
					
				
				 9 changed files with 630 additions and 3 deletions
			
			
		@ -0,0 +1,144 @@ | 
				
			||||
#include "json_lexer.h" | 
				
			||||
 | 
				
			||||
namespace Bk::Json 
 | 
				
			||||
{ | 
				
			||||
    std::string Token::to_string() | 
				
			||||
    { | 
				
			||||
        return Tools::string_format("%s %d", this->value, (int)this->type); | 
				
			||||
    } | 
				
			||||
    
 | 
				
			||||
    char Lexer::get_next_char() | 
				
			||||
    { | 
				
			||||
        char c = data.pull<char>(); | 
				
			||||
        return c; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    bool Lexer::has_more_tokens() | 
				
			||||
    { | 
				
			||||
        return (bool)data.size(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    char Lexer::get_without_white_space() | 
				
			||||
    { | 
				
			||||
        char c = ' '; | 
				
			||||
        while ((c == ' ' || c == '\n')) | 
				
			||||
        { | 
				
			||||
            c = get_next_char(); // check
 | 
				
			||||
            if ((c == ' ' || c == '\n') && !data.size()) | 
				
			||||
            { | 
				
			||||
                throw std::logic_error("Ran out of tokens"); | 
				
			||||
            } | 
				
			||||
            else if (!data.size()) | 
				
			||||
            { | 
				
			||||
                return c; | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
        return c; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    Token Lexer::get_token() | 
				
			||||
    { | 
				
			||||
        char c; | 
				
			||||
        if (!data.size()) | 
				
			||||
        { | 
				
			||||
            throw std::logic_error("Exhausted tokens"); | 
				
			||||
        } | 
				
			||||
        c = get_without_white_space(); | 
				
			||||
 | 
				
			||||
        Token token; | 
				
			||||
        if (c == '"') | 
				
			||||
        { | 
				
			||||
            token.type = TokenType::STRING; | 
				
			||||
            token.value = ""; | 
				
			||||
            c = get_next_char(); | 
				
			||||
            while (c != '"') | 
				
			||||
            { | 
				
			||||
                token.value += c; | 
				
			||||
                c = get_next_char(); | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
        else if (c == '{') | 
				
			||||
        { | 
				
			||||
            token.type = TokenType::CURLY_OPEN; | 
				
			||||
        } | 
				
			||||
        else if (c == '}') | 
				
			||||
        { | 
				
			||||
            token.type = TokenType::CURLY_CLOSE; | 
				
			||||
        } | 
				
			||||
        else if (c=='-' || (c >= '0' && c <= '9')) | 
				
			||||
        { | 
				
			||||
            token.type = TokenType::NUMBER; | 
				
			||||
            token.value = ""; | 
				
			||||
            token.value += c; | 
				
			||||
            while ((c=='-')||(c >= '0' && c <= '9') || c == '.') | 
				
			||||
            { | 
				
			||||
                c = get_next_char(); | 
				
			||||
                if (!data.size()) | 
				
			||||
                { | 
				
			||||
                    break; | 
				
			||||
                } | 
				
			||||
                else | 
				
			||||
                { | 
				
			||||
                    if ((c=='-')||(c >= '0' && c <= '9')||(c=='.')) | 
				
			||||
                    { | 
				
			||||
                        token.value += c; | 
				
			||||
                    } | 
				
			||||
                    else if (c == ',') | 
				
			||||
                    { | 
				
			||||
                        roll_back_char(c); | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                    else if (c == '\n') break; | 
				
			||||
                    else | 
				
			||||
                    { | 
				
			||||
                        throw std::logic_error("Bad Numeric format"); | 
				
			||||
                    } | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
        else if(c=='f'){ | 
				
			||||
            token.type = TokenType::BOOLEAN; | 
				
			||||
            token.value = "false"; | 
				
			||||
            data.pull<char>(4); | 
				
			||||
        } | 
				
			||||
        else if(c=='t'){ | 
				
			||||
            token.type = TokenType::BOOLEAN; | 
				
			||||
            token.value = "true"; | 
				
			||||
            data.pull<char>(3); | 
				
			||||
        } | 
				
			||||
        else if(c=='n'){ | 
				
			||||
            token.type = TokenType::NULL_TYPE; | 
				
			||||
            token.value = "null"; | 
				
			||||
            data.pull<char>(3); | 
				
			||||
        } | 
				
			||||
        else if (c == '[') | 
				
			||||
        { | 
				
			||||
            token.type = TokenType::ARRAY_OPEN; | 
				
			||||
        } | 
				
			||||
        else if (c == ']') | 
				
			||||
        { | 
				
			||||
            token.type = TokenType::ARRAY_CLOSE; | 
				
			||||
        } | 
				
			||||
        else if (c == ':') | 
				
			||||
        { | 
				
			||||
            token.type = TokenType::COLON; | 
				
			||||
        } | 
				
			||||
        else if (c == ',') | 
				
			||||
        { | 
				
			||||
            token.type = TokenType::COMMA; | 
				
			||||
        } | 
				
			||||
        lexed_token.push_back(token); | 
				
			||||
        return token; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    Token Lexer::roll_back_token() | 
				
			||||
    { | 
				
			||||
        auto token = lexed_token.back(); | 
				
			||||
        return token; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    void Lexer::roll_back_char(char c) | 
				
			||||
    { | 
				
			||||
        data.push<char>(c); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,52 @@ | 
				
			||||
#pragma once | 
				
			||||
 | 
				
			||||
#include <bakatoolspch.h> | 
				
			||||
#include <bakatools/file_system/file.h> | 
				
			||||
#include <bakatools/container/data_stream.h> | 
				
			||||
#include <bakatools/string/format.h> | 
				
			||||
#include <bakatools/logging/log.h> | 
				
			||||
#include "json_node.h" | 
				
			||||
 | 
				
			||||
namespace Bk::Json 
 | 
				
			||||
{ | 
				
			||||
    enum class TokenType | 
				
			||||
    { | 
				
			||||
        CURLY_OPEN, | 
				
			||||
        CURLY_CLOSE, | 
				
			||||
        COLON, | 
				
			||||
        STRING, | 
				
			||||
        NUMBER, | 
				
			||||
        ARRAY_OPEN, | 
				
			||||
        ARRAY_CLOSE, | 
				
			||||
        COMMA, | 
				
			||||
        BOOLEAN, | 
				
			||||
        NULL_TYPE | 
				
			||||
    }; | 
				
			||||
 | 
				
			||||
    struct Token | 
				
			||||
    { | 
				
			||||
        std::string value; | 
				
			||||
        TokenType type; | 
				
			||||
        
 | 
				
			||||
        std::string to_string(); | 
				
			||||
    }; | 
				
			||||
 | 
				
			||||
    class Lexer | 
				
			||||
    { | 
				
			||||
        std::vector<Token> lexed_token; | 
				
			||||
 | 
				
			||||
        public: | 
				
			||||
            Lexer() {} | 
				
			||||
            Lexer(Type::DataStream data) | 
				
			||||
            : data(data) {} | 
				
			||||
 | 
				
			||||
            Type::DataStream data; | 
				
			||||
 | 
				
			||||
            char get_next_char(); | 
				
			||||
            char get_without_white_space(); | 
				
			||||
            Token get_token(); | 
				
			||||
            bool has_more_tokens(); | 
				
			||||
            Token roll_back_token(); | 
				
			||||
            void roll_back_char(char c); | 
				
			||||
    }; | 
				
			||||
} | 
				
			||||
@ -0,0 +1,78 @@ | 
				
			||||
#include "json_node.h" | 
				
			||||
namespace Bk::Json 
 | 
				
			||||
{ | 
				
			||||
    void Node::set_object(Object *object) 
 | 
				
			||||
    { | 
				
			||||
        values.object = object; | 
				
			||||
        type = Type::OBJECT; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    Object Node::get_object() | 
				
			||||
    { | 
				
			||||
        if (type == Type::OBJECT) 
 | 
				
			||||
            return *values.object; | 
				
			||||
        throw std::logic_error("Improper return"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    void Node::set_list(List* list) | 
				
			||||
    { | 
				
			||||
        values.list = list; | 
				
			||||
        type = Type::LIST; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    List Node::get_list() | 
				
			||||
    { | 
				
			||||
        if (type == Type::LIST) 
 | 
				
			||||
            return *values.list; | 
				
			||||
        throw std::logic_error("Improper return"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    void Node::set_string(std::string* str) | 
				
			||||
    { | 
				
			||||
        values.s = str; | 
				
			||||
        type = Type::STRING; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    std::string Node::get_string() | 
				
			||||
    { | 
				
			||||
        if (type == Type::STRING) 
 | 
				
			||||
            return *values.s; | 
				
			||||
        throw std::logic_error("Improper return"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    void Node::set_bool(bool value) | 
				
			||||
    { | 
				
			||||
        values.bValue = value; | 
				
			||||
        type = Type::BOOLEAN; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    bool Node::get_bool() | 
				
			||||
    { | 
				
			||||
        if (type == Type::BOOLEAN) 
 | 
				
			||||
            return values.bValue; | 
				
			||||
        throw std::logic_error("Improper return"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    void Node::set_float(float value) | 
				
			||||
    { | 
				
			||||
        values.fValue = value; | 
				
			||||
        type = Type::NUMBER; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    float Node::get_float() | 
				
			||||
    { | 
				
			||||
        if (type == Type::NUMBER) 
 | 
				
			||||
            return values.fValue; | 
				
			||||
        throw std::logic_error("Improper return"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    void Node::set_null() | 
				
			||||
    { | 
				
			||||
        type = Type::NULL_TYPE; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    bool Node::is_null() | 
				
			||||
    { | 
				
			||||
        return type == Type::NULL_TYPE; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,53 @@ | 
				
			||||
#pragma once | 
				
			||||
 | 
				
			||||
#include <bakatoolspch.h> | 
				
			||||
 | 
				
			||||
namespace Bk::Json | 
				
			||||
{ | 
				
			||||
    class Node; | 
				
			||||
    
 | 
				
			||||
    using Object = std::map<std::string, std::shared_ptr<Node>>; | 
				
			||||
    using List = std::vector<std::shared_ptr<Node>>; | 
				
			||||
 | 
				
			||||
    class Node 
 | 
				
			||||
    { | 
				
			||||
        public: | 
				
			||||
            enum class Type 
 | 
				
			||||
            { 
 | 
				
			||||
                OBJECT, 
 | 
				
			||||
                LIST, 
 | 
				
			||||
                STRING, 
 | 
				
			||||
                NUMBER, 
 | 
				
			||||
                BOOLEAN, 
 | 
				
			||||
                NULL_TYPE | 
				
			||||
            }; 
 | 
				
			||||
            void set_object(Object* object); | 
				
			||||
            Object get_object(); | 
				
			||||
 | 
				
			||||
            void set_list(List* list); | 
				
			||||
            List get_list(); | 
				
			||||
 | 
				
			||||
            void set_string(std::string* str); | 
				
			||||
            std::string get_string(); | 
				
			||||
 | 
				
			||||
            void set_bool(bool value); | 
				
			||||
            bool get_bool(); | 
				
			||||
 | 
				
			||||
            void set_float(float value); | 
				
			||||
            float get_float(); | 
				
			||||
 | 
				
			||||
            void set_null(); | 
				
			||||
            bool is_null(); | 
				
			||||
 | 
				
			||||
        private: | 
				
			||||
            union Values { | 
				
			||||
                Object* object; | 
				
			||||
                List* list; | 
				
			||||
                std::string* s; | 
				
			||||
                float fValue; | 
				
			||||
                bool bValue; | 
				
			||||
            }; | 
				
			||||
            Values values; | 
				
			||||
            Type type; | 
				
			||||
    }; | 
				
			||||
} | 
				
			||||
@ -0,0 +1,264 @@ | 
				
			||||
#include "json_parser.h" | 
				
			||||
 | 
				
			||||
namespace Bk::Json | 
				
			||||
{ | 
				
			||||
    Parser::Parser(File& file) | 
				
			||||
    { | 
				
			||||
        Type::DataStream data; | 
				
			||||
        if (file.exists()) | 
				
			||||
        { | 
				
			||||
            data = file.read(file.size()); | 
				
			||||
            data.reverse(); | 
				
			||||
        } | 
				
			||||
        lexer = Lexer(data); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    Parser::Parser(const char* str, int length) | 
				
			||||
    { | 
				
			||||
        Type::DataStream data; | 
				
			||||
        data.payload = std::vector<char>(str, str + length); | 
				
			||||
        data.reverse(); | 
				
			||||
        lexer = Lexer(data); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    Parser::Parser(const std::string& str) | 
				
			||||
    { | 
				
			||||
        Type::DataStream data; | 
				
			||||
        data.payload = std::vector<char>(str.c_str(), str.c_str() + str.length()); | 
				
			||||
        data.reverse(); | 
				
			||||
        lexer = Lexer(data); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    std::shared_ptr<Json::Node> Parser::parse() 
 | 
				
			||||
    { | 
				
			||||
        Token token; | 
				
			||||
        while (lexer.has_more_tokens()) { | 
				
			||||
            try 
 | 
				
			||||
            { | 
				
			||||
                token = lexer.get_token(); | 
				
			||||
                switch (token.type) 
 | 
				
			||||
                { | 
				
			||||
                    case TokenType::CURLY_OPEN: 
 | 
				
			||||
                    { | 
				
			||||
                        std::shared_ptr<Json::Node> parsed_object = parse_object(); | 
				
			||||
                        if (!root) { | 
				
			||||
                            root = parsed_object; | 
				
			||||
                        } | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                    case TokenType::ARRAY_OPEN: { | 
				
			||||
                        std::shared_ptr<Json::Node> parsed_list = parse_list(); | 
				
			||||
                        if (!root) { | 
				
			||||
                            root = parsed_list; | 
				
			||||
                        } | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
 | 
				
			||||
                    case TokenType::STRING: { | 
				
			||||
                        
 | 
				
			||||
                        std::shared_ptr<Json::Node> parsed_string = parse_string(); | 
				
			||||
                        if (!root) { | 
				
			||||
                            root = parsed_string; | 
				
			||||
                        } | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                    case TokenType::NUMBER: { | 
				
			||||
                        std::shared_ptr<Json::Node> parsed_number = parse_number(); | 
				
			||||
                        if (!root) { | 
				
			||||
                            root = parsed_number; | 
				
			||||
                        } | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                    
 | 
				
			||||
                    case TokenType::BOOLEAN: { | 
				
			||||
                        std::shared_ptr<Json::Node> parsed_boolean = parse_boolean(); | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
            catch(std::logic_error e) | 
				
			||||
            { | 
				
			||||
                BK_INFO(e.what()); | 
				
			||||
                auto node = std::shared_ptr<Json::Node>(); | 
				
			||||
                node->set_null(); | 
				
			||||
                root = node; | 
				
			||||
                break; | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
        return root; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    std::shared_ptr<Json::Node> Parser::parse_list() 
 | 
				
			||||
    { | 
				
			||||
        std::shared_ptr<Json::Node> node = std::make_shared<Json::Node>(); | 
				
			||||
        Json::List *list = new Json::List(); | 
				
			||||
        bool has_completed = false; | 
				
			||||
        Token next_token; | 
				
			||||
        while (!has_completed) { | 
				
			||||
            if (!lexer.has_more_tokens()) 
 | 
				
			||||
            { | 
				
			||||
                throw std::logic_error("No more tokens"); | 
				
			||||
            } 
 | 
				
			||||
            else 
 | 
				
			||||
            { | 
				
			||||
                next_token = lexer.get_token(); | 
				
			||||
                if (next_token.type == TokenType::COLON || next_token.type == TokenType::COMMA) | 
				
			||||
                    continue; | 
				
			||||
                std::shared_ptr<Json::Node> node; | 
				
			||||
                switch (next_token.type) 
 | 
				
			||||
                { | 
				
			||||
                    case TokenType::ARRAY_OPEN: 
 | 
				
			||||
                    { | 
				
			||||
                        node = parse_list(); | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                    case TokenType::CURLY_OPEN: 
 | 
				
			||||
                    { | 
				
			||||
                        node = parse_object(); | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                    case TokenType::STRING: 
 | 
				
			||||
                    { | 
				
			||||
                        node = parse_string(); | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                    case TokenType::NUMBER: 
 | 
				
			||||
                    { | 
				
			||||
                        node = parse_number(); | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                    case TokenType::BOOLEAN: 
 | 
				
			||||
                    { | 
				
			||||
                        node = parse_boolean(); | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                    case TokenType::NULL_TYPE: { | 
				
			||||
                        node = parse_null(); | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                } | 
				
			||||
                list->push_back(node); | 
				
			||||
                if (next_token.type == TokenType::ARRAY_CLOSE) { | 
				
			||||
                    has_completed = true; | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
        node->set_list(list); | 
				
			||||
        return node; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    std::shared_ptr<Json::Node> Parser::parse_object() 
 | 
				
			||||
    { | 
				
			||||
        std::string key = ""; | 
				
			||||
        std::shared_ptr<Json::Node> node = std::make_shared<Json::Node>(); | 
				
			||||
        Json::Object *key_object_map = new Json::Object(); | 
				
			||||
        bool has_completed = false; | 
				
			||||
        bool no_key = true; | 
				
			||||
        Token next_token; | 
				
			||||
        while (!has_completed) 
 | 
				
			||||
        { | 
				
			||||
            if (lexer.has_more_tokens()) 
 | 
				
			||||
            { | 
				
			||||
                if (no_key) | 
				
			||||
                { | 
				
			||||
                    next_token = lexer.get_token(); | 
				
			||||
                    if (next_token.type == TokenType::CURLY_CLOSE) 
 | 
				
			||||
                    { | 
				
			||||
                        has_completed = true; | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                    if (next_token.type == TokenType::COLON || next_token.type == TokenType::COMMA) | 
				
			||||
                        continue; | 
				
			||||
                    key = next_token.value; | 
				
			||||
                    no_key = false; | 
				
			||||
                } | 
				
			||||
                next_token = lexer.get_token(); | 
				
			||||
                if (next_token.type == TokenType::COLON || next_token.type == TokenType::COMMA) | 
				
			||||
                    continue; | 
				
			||||
                std::shared_ptr<Json::Node> node; | 
				
			||||
                switch (next_token.type) 
 | 
				
			||||
                { | 
				
			||||
                    case TokenType::STRING: 
 | 
				
			||||
                    { | 
				
			||||
                        (*key_object_map)[key] = parse_string(); | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                    case TokenType::ARRAY_OPEN: 
 | 
				
			||||
                    { | 
				
			||||
                        (*key_object_map)[key] = parse_list(); | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                    case TokenType::NUMBER: 
 | 
				
			||||
                    { | 
				
			||||
                        (*key_object_map)[key] = parse_number(); | 
				
			||||
                    break; | 
				
			||||
                    } | 
				
			||||
                    case TokenType::CURLY_OPEN: 
 | 
				
			||||
                    { | 
				
			||||
                        (*key_object_map)[key] = parse_object(); | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                    case TokenType::BOOLEAN: 
 | 
				
			||||
                    { | 
				
			||||
                        (*key_object_map)[key] = parse_boolean(); | 
				
			||||
                        break; | 
				
			||||
 | 
				
			||||
                    } | 
				
			||||
                    case TokenType::NULL_TYPE: 
 | 
				
			||||
                    { | 
				
			||||
                        (*key_object_map)[key] = parse_null(); | 
				
			||||
                        break; | 
				
			||||
                    } | 
				
			||||
                } | 
				
			||||
                if (next_token.type == TokenType::CURLY_CLOSE) 
 | 
				
			||||
                { | 
				
			||||
                    has_completed = true; | 
				
			||||
                    break; | 
				
			||||
                } | 
				
			||||
                no_key = true; | 
				
			||||
                key = ""; | 
				
			||||
            } | 
				
			||||
            else 
 | 
				
			||||
            { | 
				
			||||
                throw std::logic_error("No more tokens"); | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
        node->set_object(key_object_map); | 
				
			||||
        return node;    
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    std::shared_ptr<Json::Node> Parser::parse_string() 
 | 
				
			||||
    { | 
				
			||||
        std::shared_ptr<Json::Node> node = std::make_shared<Json::Node>(); | 
				
			||||
        Token token = lexer.roll_back_token(); | 
				
			||||
        std::string *sValue = new std::string(token.value); | 
				
			||||
        node->set_string(sValue); | 
				
			||||
        return node; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    std::shared_ptr<Json::Node> Parser::parse_number() 
 | 
				
			||||
    { | 
				
			||||
        std::shared_ptr<Json::Node> node = std::make_shared<Json::Node>(); | 
				
			||||
        Token token = lexer.roll_back_token(); | 
				
			||||
        float fValue = std::stof(token.value); | 
				
			||||
        node->set_float(fValue); | 
				
			||||
        return node; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    std::shared_ptr<Json::Node> Parser::parse_boolean() 
 | 
				
			||||
    { | 
				
			||||
        std::shared_ptr<Json::Node> node = std::make_shared<Json::Node>(); | 
				
			||||
        Token token = lexer.roll_back_token(); | 
				
			||||
        bool bValue = token.value == "True" ? true : false; | 
				
			||||
        node->set_bool(bValue); | 
				
			||||
        return node; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    std::shared_ptr<Json::Node> Parser::parse_null() 
 | 
				
			||||
    { | 
				
			||||
        std::shared_ptr<Json::Node> node = std::make_shared<Json::Node>(); | 
				
			||||
        Token token = lexer.roll_back_token(); | 
				
			||||
        node->set_null(); | 
				
			||||
        return node; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,32 @@ | 
				
			||||
#pragma once | 
				
			||||
 | 
				
			||||
#include <bakatoolspch.h> | 
				
			||||
#include <bakatools/file_system/file.h> | 
				
			||||
#include <bakatools/container/data_stream.h> | 
				
			||||
#include "json_lexer.h" | 
				
			||||
 | 
				
			||||
namespace Bk::Json | 
				
			||||
{ | 
				
			||||
    class Parser { | 
				
			||||
        Type::DataStream data; | 
				
			||||
        std::shared_ptr<Json::Node> root; | 
				
			||||
        std::unique_ptr<Json::Node> current; | 
				
			||||
        Lexer lexer; | 
				
			||||
        
 | 
				
			||||
        std::shared_ptr<Json::Node> parse_object(); | 
				
			||||
        std::shared_ptr<Json::Node> parse_string(); | 
				
			||||
        std::shared_ptr<Json::Node> parse_number(); | 
				
			||||
        std::shared_ptr<Json::Node> parse_list(); | 
				
			||||
        std::shared_ptr<Json::Node> parse_boolean(); | 
				
			||||
        std::shared_ptr<Json::Node> parse_null(); | 
				
			||||
 | 
				
			||||
        public: | 
				
			||||
            Parser(const Type::DataStream data) | 
				
			||||
            :lexer(data) {} | 
				
			||||
            Parser(File& file); | 
				
			||||
            Parser(const char* data, int length); | 
				
			||||
            Parser(const std::string& str); | 
				
			||||
 | 
				
			||||
            std::shared_ptr<Json::Node> parse(); | 
				
			||||
    }; | 
				
			||||
} | 
				
			||||
					Loading…
					
					
				
		Reference in New Issue