🔥 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) | ||||
|  |  | |||
|  | @ -3409,6 +3409,80 @@ 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; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -3540,7 +3614,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; | ||||
|         } | ||||
|  | @ -3839,119 +3915,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