🔨 using a vector<bool> for the parser hierarchy

This commit is contained in:
Niels Lohmann 2018-03-29 18:45:43 +02:00
parent 5f723bbec6
commit 850671b9f1
No known key found for this signature in database
GPG key ID: 7F3CEA63AE251B69
2 changed files with 166 additions and 180 deletions

View file

@ -162,10 +162,9 @@ class parser
private: private:
bool sax_parse_internal(json_sax_t* sax) bool sax_parse_internal(json_sax_t* sax)
{ {
// two values for the structured values
enum class parse_state_t { array_value, object_value };
// stack to remember the hieararchy of structured values we are parsing // stack to remember the hieararchy of structured values we are parsing
std::vector<parse_state_t> states; // true = array; false = object
std::vector<bool> states;
// value to avoid a goto (see comment where set to true) // value to avoid a goto (see comment where set to true)
bool skip_to_state_evaluation = false; bool skip_to_state_evaluation = false;
@ -221,7 +220,7 @@ class parser
} }
// remember we are now inside an object // remember we are now inside an object
states.push_back(parse_state_t::object_value); states.push_back(false);
// parse values // parse values
get_token(); get_token();
@ -249,7 +248,7 @@ class parser
} }
// remember we are now inside an array // remember we are now inside an array
states.push_back(parse_state_t::array_value); states.push_back(true);
// parse values (no need to call get_token) // parse values (no need to call get_token)
continue; continue;
@ -359,9 +358,7 @@ class parser
else else
{ {
get_token(); get_token();
switch (states.back()) if (states.back()) // array
{
case parse_state_t::array_value:
{ {
// comma -> next value // comma -> next value
if (last_token == token_type::value_separator) if (last_token == token_type::value_separator)
@ -379,11 +376,10 @@ class parser
return false; return false;
} }
// We are done with this array. Before we can parse // We are done with this array. Before we can parse a
// a new value, we need to evaluate the new state // new value, we need to evaluate the new state first.
// first. By setting skip_to_state_evaluation to // By setting skip_to_state_evaluation to false, we
// false, we are effectively jumping to the // are effectively jumping to the beginning of this if.
// beginning of this switch.
assert(not states.empty()); assert(not states.empty());
states.pop_back(); states.pop_back();
skip_to_state_evaluation = true; skip_to_state_evaluation = true;
@ -396,8 +392,7 @@ class parser
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array))); parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array)));
} }
} }
else // object
case parse_state_t::object_value:
{ {
// comma -> next value // comma -> next value
if (last_token == token_type::value_separator) if (last_token == token_type::value_separator)
@ -441,11 +436,10 @@ class parser
return false; return false;
} }
// We are done with this object. Before we can // We are done with this object. Before we can parse a
// parse a new value, we need to evaluate the new // new value, we need to evaluate the new state first.
// state first. By setting skip_to_state_evaluation // By setting skip_to_state_evaluation to false, we
// to false, we are effectively jumping to the // are effectively jumping to the beginning of this if.
// beginning of this switch.
assert(not states.empty()); assert(not states.empty());
states.pop_back(); states.pop_back();
skip_to_state_evaluation = true; skip_to_state_evaluation = true;
@ -461,7 +455,6 @@ class parser
} }
} }
} }
}
/// get next token from lexer /// get next token from lexer
token_type get_token() token_type get_token()

View file

@ -3955,10 +3955,9 @@ class parser
private: private:
bool sax_parse_internal(json_sax_t* sax) bool sax_parse_internal(json_sax_t* sax)
{ {
// two values for the structured values
enum class parse_state_t { array_value, object_value };
// stack to remember the hieararchy of structured values we are parsing // stack to remember the hieararchy of structured values we are parsing
std::vector<parse_state_t> states; // true = array; false = object
std::vector<bool> states;
// value to avoid a goto (see comment where set to true) // value to avoid a goto (see comment where set to true)
bool skip_to_state_evaluation = false; bool skip_to_state_evaluation = false;
@ -4014,7 +4013,7 @@ class parser
} }
// remember we are now inside an object // remember we are now inside an object
states.push_back(parse_state_t::object_value); states.push_back(false);
// parse values // parse values
get_token(); get_token();
@ -4042,7 +4041,7 @@ class parser
} }
// remember we are now inside an array // remember we are now inside an array
states.push_back(parse_state_t::array_value); states.push_back(true);
// parse values (no need to call get_token) // parse values (no need to call get_token)
continue; continue;
@ -4152,9 +4151,7 @@ class parser
else else
{ {
get_token(); get_token();
switch (states.back()) if (states.back()) // array
{
case parse_state_t::array_value:
{ {
// comma -> next value // comma -> next value
if (last_token == token_type::value_separator) if (last_token == token_type::value_separator)
@ -4172,11 +4169,10 @@ class parser
return false; return false;
} }
// We are done with this array. Before we can parse // We are done with this array. Before we can parse a
// a new value, we need to evaluate the new state // new value, we need to evaluate the new state first.
// first. By setting skip_to_state_evaluation to // By setting skip_to_state_evaluation to false, we
// false, we are effectively jumping to the // are effectively jumping to the beginning of this if.
// beginning of this switch.
assert(not states.empty()); assert(not states.empty());
states.pop_back(); states.pop_back();
skip_to_state_evaluation = true; skip_to_state_evaluation = true;
@ -4189,8 +4185,7 @@ class parser
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array))); parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array)));
} }
} }
else // object
case parse_state_t::object_value:
{ {
// comma -> next value // comma -> next value
if (last_token == token_type::value_separator) if (last_token == token_type::value_separator)
@ -4234,11 +4229,10 @@ class parser
return false; return false;
} }
// We are done with this object. Before we can // We are done with this object. Before we can parse a
// parse a new value, we need to evaluate the new // new value, we need to evaluate the new state first.
// state first. By setting skip_to_state_evaluation // By setting skip_to_state_evaluation to false, we
// to false, we are effectively jumping to the // are effectively jumping to the beginning of this if.
// beginning of this switch.
assert(not states.empty()); assert(not states.empty());
states.pop_back(); states.pop_back();
skip_to_state_evaluation = true; skip_to_state_evaluation = true;
@ -4254,7 +4248,6 @@ class parser
} }
} }
} }
}
/// get next token from lexer /// get next token from lexer
token_type get_token() token_type get_token()