🔥 replaced acceptor with SAX parser
This commit is contained in:
		
							parent
							
								
									303a0c5843
								
							
						
					
					
						commit
						8b379948d0
					
				
					 3 changed files with 154 additions and 228 deletions
				
			
		| 
						 | 
				
			
			@ -275,5 +275,79 @@ class json_sax_dom_parser : public json_sax<BasicJsonType>
 | 
			
		|||
    const bool allow_exceptions = true;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename BasicJsonType>
 | 
			
		||||
class json_sax_acceptor : public json_sax<BasicJsonType>
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
    using number_integer_t = typename BasicJsonType::number_integer_t;
 | 
			
		||||
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
 | 
			
		||||
    using number_float_t = typename BasicJsonType::number_float_t;
 | 
			
		||||
 | 
			
		||||
    bool null() override
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool boolean(bool) override
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool number_integer(number_integer_t) override
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool number_unsigned(number_unsigned_t) override
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool number_float(number_float_t, const std::string&) override
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool string(std::string&&) override
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool start_object(std::size_t) override
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool key(std::string&&) override
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool end_object() override
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool start_array(std::size_t) override
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool end_array() override
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool binary(const std::vector<uint8_t>&) override
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool parse_error(std::size_t, const std::string&, const std::string&) override
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -137,7 +137,9 @@ class parser
 | 
			
		|||
    */
 | 
			
		||||
    bool accept(const bool strict = true)
 | 
			
		||||
    {
 | 
			
		||||
        if (not accept_internal())
 | 
			
		||||
        json_sax_acceptor<BasicJsonType> sax_acceptor;
 | 
			
		||||
 | 
			
		||||
        if (not sax_parse_internal(&sax_acceptor))
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -436,119 +438,6 @@ class parser
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*!
 | 
			
		||||
    @brief the actual acceptor
 | 
			
		||||
 | 
			
		||||
    @invariant 1. The last token is not yet processed. Therefore, the caller
 | 
			
		||||
                  of this function must make sure a token has been read.
 | 
			
		||||
               2. When this function returns, the last token is processed.
 | 
			
		||||
                  That is, the last read character was already considered.
 | 
			
		||||
 | 
			
		||||
    This invariant makes sure that no token needs to be "unput".
 | 
			
		||||
    */
 | 
			
		||||
    bool accept_internal()
 | 
			
		||||
    {
 | 
			
		||||
        switch (last_token)
 | 
			
		||||
        {
 | 
			
		||||
            case token_type::begin_object:
 | 
			
		||||
            {
 | 
			
		||||
                // read next token
 | 
			
		||||
                get_token();
 | 
			
		||||
 | 
			
		||||
                // closing } -> we are done
 | 
			
		||||
                if (last_token == token_type::end_object)
 | 
			
		||||
                {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // parse values
 | 
			
		||||
                while (true)
 | 
			
		||||
                {
 | 
			
		||||
                    // parse key
 | 
			
		||||
                    if (last_token != token_type::value_string)
 | 
			
		||||
                    {
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // parse separator (:)
 | 
			
		||||
                    get_token();
 | 
			
		||||
                    if (last_token != token_type::name_separator)
 | 
			
		||||
                    {
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // parse value
 | 
			
		||||
                    get_token();
 | 
			
		||||
                    if (not accept_internal())
 | 
			
		||||
                    {
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // comma -> next value
 | 
			
		||||
                    get_token();
 | 
			
		||||
                    if (last_token == token_type::value_separator)
 | 
			
		||||
                    {
 | 
			
		||||
                        get_token();
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // closing }
 | 
			
		||||
                    return (last_token == token_type::end_object);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case token_type::begin_array:
 | 
			
		||||
            {
 | 
			
		||||
                // read next token
 | 
			
		||||
                get_token();
 | 
			
		||||
 | 
			
		||||
                // closing ] -> we are done
 | 
			
		||||
                if (last_token == token_type::end_array)
 | 
			
		||||
                {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // parse values
 | 
			
		||||
                while (true)
 | 
			
		||||
                {
 | 
			
		||||
                    // parse value
 | 
			
		||||
                    if (not accept_internal())
 | 
			
		||||
                    {
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // comma -> next value
 | 
			
		||||
                    get_token();
 | 
			
		||||
                    if (last_token == token_type::value_separator)
 | 
			
		||||
                    {
 | 
			
		||||
                        get_token();
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // closing ]
 | 
			
		||||
                    return (last_token == token_type::end_array);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case token_type::value_float:
 | 
			
		||||
            {
 | 
			
		||||
                // reject infinity or NAN
 | 
			
		||||
                return std::isfinite(m_lexer.get_number_float());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case token_type::literal_false:
 | 
			
		||||
            case token_type::literal_null:
 | 
			
		||||
            case token_type::literal_true:
 | 
			
		||||
            case token_type::value_integer:
 | 
			
		||||
            case token_type::value_string:
 | 
			
		||||
            case token_type::value_unsigned:
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            default: // the last token was unexpected
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool sax_parse_internal(json_sax_t* sax)
 | 
			
		||||
    {
 | 
			
		||||
        switch (last_token)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue