-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjson_grammar.hpp
124 lines (94 loc) · 2.88 KB
/
json_grammar.hpp
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#ifndef _JSON_GRAMMAR_H_
#define _JSON_GRAMMAR_H_
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_container.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include "json_types.hpp"
namespace json_qi {
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
template <typename InputIterator>
struct json_grammar
: qi::grammar<InputIterator, json_object(), ascii::space_type> {
json_grammar()
: json_grammar::base_type(json_object_) {
json_object_ %=
json_string_
| json_float_
| json_int_
| json_subobject_
| json_array_
;
json_string_ %=
(qi::lit("'")
>> qi::lexeme[*(qi::char_ - qi::char_('\''))]
>> (qi::lit("'")))
| (
qi::lit("\"")
>> qi::lexeme[*(qi::char_ - qi::char_('"'))]
>> (qi::lit("\"")))
;
json_float_ %= qi::double_;
json_int_ %= qi::int_;
json_subobject_ %=
qi::lit("{")
>> json_subobject_map_
>> qi::lit("}")
;
json_subobject_map_ =
(
(json_string_
>> qi::lit(":")
>> json_object_)[phoenix::insert(qi::_val
, phoenix::construct
<json_subobject::object_map::value_type>(qi::_1
, qi::_2))]
) % ','
;
json_array_ %= qi::lit("[") >> (json_object_ % ',') >> qi::lit("]");
}
qi::rule<InputIterator, json_object(), ascii::space_type> json_object_;
qi::rule<InputIterator, json_string_type(), ascii::space_type> json_string_;
qi::rule<InputIterator, json_float_type(), ascii::space_type> json_float_;
qi::rule<InputIterator, json_int_type(), ascii::space_type> json_int_;
qi::rule<InputIterator, json_subobject(), ascii::space_type> json_subobject_;
qi::rule<InputIterator, json_subobject::object_map(), ascii::space_type> json_subobject_map_;
qi::rule<InputIterator, json_array(), ascii::space_type> json_array_;
};
class json_map {
public:
json_map(json_object& obj)
: m_obj(obj), m_obj_(0) {}
json_map(std::string& json_in)
: m_obj(m_obj_) {
json_grammar<std::string::iterator> jg;
std::string::iterator start_it(json_in.begin());
if(!qi::phrase_parse(start_it
, json_in.end()
, jg
, boost::spirit::ascii::space
, m_obj_)) {
throw;
}
}
json_map operator[](const json_string_type& key) {
return json_map(boost::get<json_subobject>(m_obj).contents[key]);
}
json_map operator[](size_t index) {
return json_map(boost::get<json_array>(m_obj).contents[index]);
}
json_object& operator()() {
return m_obj;
}
void push_back(const json_object& obj) {
boost::get<json_array>(m_obj).contents.push_back(obj);
}
void insert(const json_subobject::object_map::value_type& val) {
boost::get<json_subobject>(m_obj).contents.insert(val);
}
json_object& m_obj;
json_object m_obj_;
};
}
#endif