-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjson.cpp
More file actions
88 lines (76 loc) · 2.47 KB
/
Copy pathjson.cpp
File metadata and controls
88 lines (76 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// Copyright (C) 2014, Richard Thomson. All rights reserved.
#include "json.h"
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <stdexcept>
using namespace boost::spirit::qi;
namespace
{
typedef std::pair<std::string, json::value> key_value_pair;
}
BOOST_FUSION_ADAPT_STRUCT(::key_value_pair,
(std::string, first)
(json::value, second)
);
namespace
{
typedef ascii::space_type skipper;
template <typename Iter>
struct json_grammar : grammar<Iter, json::value(), skipper>
{
json_grammar() : json_grammar::base_type(start)
{
boolean = bool_;
integer = int_ >> !no_case[char_(".e")];
number = double_;
escapes.add(R"(\")", '"')
(R"(\\)", '\\')
(R"(\/)", '/')
(R"(\b)", '\b')
(R"(\f)", '\f')
(R"(\n)", '\n')
(R"(\r)", '\r')
(R"(\t)", '\t');
uint_parser<char, 16, 2, 2> hex_ascii_char;
unicode_escape = R"(\u00)" >> hex_ascii_char;
quoted_string = lexeme['"' >>
*(escapes | unicode_escape | (char_ - '"' - '\\'))
>> '"'];
array_value = '[' >> ((value % ',') | eps) >> ']';
key_value = quoted_string >> ':' >> value;
object_value = ('{' >> ((key_value % ',') | eps) >> '}');
null_value = lit("null") >> attr(json::null());
value = boolean | integer | number | quoted_string
| array_value | object_value | null_value;
start = value;
}
rule<Iter, json::value(), skipper> start;
rule<Iter, json::null(), skipper> null_value;
rule<Iter, bool(), skipper> boolean;
rule<Iter, int(), skipper> integer;
rule<Iter, double(), skipper> number;
rule<Iter, std::string(), skipper> quoted_string;
rule<Iter, char()> unicode_escape;
symbols<char const, char const> escapes;
rule<Iter, json::value(), skipper> value;
rule<Iter, json::array(), skipper> array_value;
rule<Iter, key_value_pair(), skipper> key_value;
rule<Iter, json::object(), skipper> object_value;
};
}
namespace json
{
value parse(std::string const& text)
{
std::string::const_iterator start{text.begin()};
value result;
if (phrase_parse(start, text.end(),
json_grammar<std::string::const_iterator>(),
ascii::space, result)
&& start == text.end())
{
return result;
}
throw std::domain_error("invalid JSON input");
}
}