| 252 | }; |
| 253 | |
| 254 | bool Parser::parseValue(Value &Out) { |
| 255 | eatWhitespace(); |
| 256 | if (P == End) |
| 257 | return parseError("Unexpected EOF"); |
| 258 | switch (char C = next()) { |
| 259 | // Bare null/true/false are easy - first char identifies them. |
| 260 | case 'n': |
| 261 | Out = nullptr; |
| 262 | return (next() == 'u' && next() == 'l' && next() == 'l') || |
| 263 | parseError("Invalid JSON value (null?)"); |
| 264 | case 't': |
| 265 | Out = true; |
| 266 | return (next() == 'r' && next() == 'u' && next() == 'e') || |
| 267 | parseError("Invalid JSON value (true?)"); |
| 268 | case 'f': |
| 269 | Out = false; |
| 270 | return (next() == 'a' && next() == 'l' && next() == 's' && next() == 'e') || |
| 271 | parseError("Invalid JSON value (false?)"); |
| 272 | case '"': { |
| 273 | std::string S; |
| 274 | if (parseString(S)) { |
| 275 | Out = std::move(S); |
| 276 | return true; |
| 277 | } |
| 278 | return false; |
| 279 | } |
| 280 | case '[': { |
| 281 | Out = Array{}; |
| 282 | Array &A = *Out.getAsArray(); |
| 283 | eatWhitespace(); |
| 284 | if (peek() == ']') { |
| 285 | ++P; |
| 286 | return true; |
| 287 | } |
| 288 | for (;;) { |
| 289 | A.emplace_back(nullptr); |
| 290 | if (!parseValue(A.back())) |
| 291 | return false; |
| 292 | eatWhitespace(); |
| 293 | switch (next()) { |
| 294 | case ',': |
| 295 | eatWhitespace(); |
| 296 | continue; |
| 297 | case ']': |
| 298 | return true; |
| 299 | default: |
| 300 | return parseError("Expected , or ] after array element"); |
| 301 | } |
| 302 | } |
| 303 | } |
| 304 | case '{': { |
| 305 | Out = Object{}; |
| 306 | Object &O = *Out.getAsObject(); |
| 307 | eatWhitespace(); |
| 308 | if (peek() == '}') { |
| 309 | ++P; |
| 310 | return true; |
| 311 | } |
no test coverage detected