-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjson_parser.h
More file actions
54 lines (43 loc) · 2.16 KB
/
json_parser.h
File metadata and controls
54 lines (43 loc) · 2.16 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
#ifndef JSON_PARSER_H
#define JSON_PARSER_H
#include "json_value.h"
#include "anpa/anpa.h"
using namespace anpa;
//Remove whitespace (if any) before evaluating `p`
template <typename Parser>
constexpr auto eat(Parser p) {
return trim() >> p;
}
constexpr auto string_parser = []() {
constexpr auto unicode = item<'u'>() >> times<4>(item_if([](const auto& f) {return std::isxdigit(f);}));
constexpr auto escaped = item<'\\'>() >> (unicode || any_of<'"','\\','/','b','f','n','r','t'>());
constexpr auto notEnd = escaped | item_if_not([](auto c) {
return c == '"' || static_cast<std::make_unsigned_t<decltype(c)>>(c) < 0x20;
});
return lift_value<json_string>(item<'"'>() >> many(notEnd) << item<'"'>());
}();
constexpr auto number_parser = floating<json_number, options::no_leading_zero>();
constexpr auto bool_parser = seq<'t','r','u','e'>() >> mreturn<true>() ||
seq<'f','a','l','s','e'>() >> mreturn<false>();
constexpr auto null_parser = seq<'n','u','l','l'>() >> mreturn_emplace<json_null>();
template <typename P>
constexpr auto get_object_parser(P value_parser) {
auto shared_value_parser = lift([](auto&& r) {
return std::make_shared<json_value>(std::forward<decltype(r)>(r));
}, value_parser);
return item<'{'>() >> many_to_map<options::no_trailing_separator>(eat(string_parser),
eat(item<':'>() >> shared_value_parser),
eat(item<','>())) << eat(item<'}'>());
}
template <typename P>
constexpr auto get_array_parser(P value_parser) {
return item<'['>() >> many_to_vector<options::no_trailing_separator>(value_parser, eat(item<','>())) << eat(item<']'>());
}
constexpr auto json_parser = recursive<json_value>([](auto val_parser) {
return eat(lift_or_value<json_value>(string_parser, number_parser,
get_object_parser(val_parser), get_array_parser(val_parser),
bool_parser, null_parser));
});
constexpr auto array_parser = get_array_parser(json_parser);
constexpr auto object_parser = get_object_parser(json_parser);
#endif // JSON_PARSER_H