13 Object, Array, String, Number, Boolean, Null
17 bool operator()(
const std::string& a,
const std::string& b)
const {
18 bool a_numeric = isNumeric(a);
19 bool b_numeric = isNumeric(b);
21 if (a_numeric && b_numeric) {
22 return std::stod(a) < std::stod(b);
28 bool isNumeric(
const std::string& s)
const {
30 std::strtod(s.c_str(), &end);
31 return end != s.c_str() && *end ==
'\0';
45 explicit JsonParser(
const std::string& input) : input(input), pos(0) {}
48 std::stringstream buffer;
49 buffer << file.rdbuf();
53 pos = input.find(
'{');
54 input = input.substr(pos);
62 throw std::runtime_error(
"Unexpected characters at end of input.");
71 void skipWhitespace() {
72 while (!eof() && std::isspace(input[pos])) {
78 return pos >= input.size();
92 throw std::runtime_error(
"Unexpected end of input.");
96 if (ch ==
'{')
return parseObject();
97 if (ch ==
'[')
return parseArray();
98 if (ch ==
'\"' || ch ==
'\'')
return parseString();
99 if (std::isdigit(ch) || ch ==
'-')
return parseNumber();
100 if (ch ==
't' || ch ==
'T' || ch ==
'f' || ch ==
'F')
return parseBoolean();
101 if (ch ==
'n')
return parseNull();
103 throw std::runtime_error(
"Unexpected character.");
109 obj.type = JsonType::Object;
120 if (std::isdigit(peek()) || peek() ==
'-') {
122 key.type = JsonType::String;
123 key.str = std::to_string(key.num);
125 else if (peek() ==
'\"' || peek() ==
'\'') {
129 if (consume() !=
':') {
130 throw std::runtime_error(
"Expected ':' after key in object.");
133 obj.obj[key.str] = value;
137 if (ch ==
'}' || ch ==
'\0')
break;
139 throw std::runtime_error(
"Expected ',' or '}' in object.");
148 array.type = JsonType::Array;
158 array.arr.push_back(value);
162 if (ch ==
']')
break;
164 throw std::runtime_error(
"Expected ',' or ']' in array.");
171 std::ostringstream result;
174 if (eof())
throw std::runtime_error(
"Unexpected end of input during string parsing.");
177 if (ch ==
'\"' || ch ==
'\'')
break;
179 if (eof())
throw std::runtime_error(
"Unexpected end of input during escape sequence.");
180 char esc = consume();
182 case '\"': result <<
'\"';
break;
183 case '\'': result <<
'\'';
break;
184 case '\\': result <<
'\\';
break;
185 case '/': result <<
'/';
break;
186 case 'b': result <<
'\b';
break;
187 case 'f': result <<
'\f';
break;
188 case 'n': result <<
'\n';
break;
189 case 'r': result <<
'\r';
break;
190 case 't': result <<
'\t';
break;
191 default:
throw std::runtime_error(
"Invalid escape sequence.");
200 strValue.type = JsonType::String;
201 strValue.str = result.str();
206 std::ostringstream result;
211 while (!eof() && (std::isdigit(peek()) || peek() ==
'.')) {
214 if (!eof() && (peek() ==
'e' || peek() ==
'E')) {
217 if (!eof() && (peek() ==
'+' || peek() ==
'-')) {
221 while (!eof() && std::isdigit(peek())) {
227 number.type = JsonType::Number;
228 number.num = std::stod(result.str());
233 std::ostringstream result;
234 for (
int i = 0; i < 4 && !eof(); ++i) {
239 boolValue.type = JsonType::Boolean;
240 std::string res = result.str();
241 if (res ==
"true" || res ==
"True") {
242 boolValue.boolean =
true;
244 else if (res ==
"false" || res ==
"False") {
245 boolValue.boolean =
false;
248 throw std::runtime_error(
"Invalid value for boolean.");
255 for (
int i = 0; i < 4 && !eof(); ++i) {
258 if (result !=
"null") {
259 throw std::runtime_error(
"Invalid value for null.");
262 nullValue.type = JsonType::Null;