jsoncons 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +7 -0
  2. data/ext/jsoncons/extconf.rb +43 -0
  3. data/ext/jsoncons/jsoncons.cpp +161 -0
  4. data/ext/jsoncons/jsoncons.h +10 -0
  5. data/jsoncons.gemspec +44 -0
  6. data/lib/jsoncons/jsoncons/examples/input/address-book.json +13 -0
  7. data/lib/jsoncons/jsoncons/examples/input/books.json +28 -0
  8. data/lib/jsoncons/jsoncons/examples/input/countries.json +7 -0
  9. data/lib/jsoncons/jsoncons/examples/input/employees.json +30 -0
  10. data/lib/jsoncons/jsoncons/examples/input/jsonschema/name.json +15 -0
  11. data/lib/jsoncons/jsoncons/examples/input/multiple-json-objects.json +3 -0
  12. data/lib/jsoncons/jsoncons/examples/input/sales.csv +6 -0
  13. data/lib/jsoncons/jsoncons/examples/input/store.json +28 -0
  14. data/lib/jsoncons/jsoncons/examples/input/tasks.csv +6 -0
  15. data/lib/jsoncons/jsoncons/include/jsoncons/allocator_holder.hpp +38 -0
  16. data/lib/jsoncons/jsoncons/include/jsoncons/basic_json.hpp +5905 -0
  17. data/lib/jsoncons/jsoncons/include/jsoncons/bigint.hpp +1611 -0
  18. data/lib/jsoncons/jsoncons/include/jsoncons/byte_string.hpp +820 -0
  19. data/lib/jsoncons/jsoncons/include/jsoncons/config/binary_config.hpp +226 -0
  20. data/lib/jsoncons/jsoncons/include/jsoncons/config/compiler_support.hpp +375 -0
  21. data/lib/jsoncons/jsoncons/include/jsoncons/config/jsoncons_config.hpp +309 -0
  22. data/lib/jsoncons/jsoncons/include/jsoncons/config/version.hpp +40 -0
  23. data/lib/jsoncons/jsoncons/include/jsoncons/conv_error.hpp +218 -0
  24. data/lib/jsoncons/jsoncons/include/jsoncons/decode_json.hpp +209 -0
  25. data/lib/jsoncons/jsoncons/include/jsoncons/decode_traits.hpp +651 -0
  26. data/lib/jsoncons/jsoncons/include/jsoncons/detail/endian.hpp +44 -0
  27. data/lib/jsoncons/jsoncons/include/jsoncons/detail/grisu3.hpp +312 -0
  28. data/lib/jsoncons/jsoncons/include/jsoncons/detail/optional.hpp +483 -0
  29. data/lib/jsoncons/jsoncons/include/jsoncons/detail/parse_number.hpp +1133 -0
  30. data/lib/jsoncons/jsoncons/include/jsoncons/detail/span.hpp +188 -0
  31. data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_view.hpp +537 -0
  32. data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_wrapper.hpp +370 -0
  33. data/lib/jsoncons/jsoncons/include/jsoncons/detail/write_number.hpp +567 -0
  34. data/lib/jsoncons/jsoncons/include/jsoncons/encode_json.hpp +315 -0
  35. data/lib/jsoncons/jsoncons/include/jsoncons/encode_traits.hpp +378 -0
  36. data/lib/jsoncons/jsoncons/include/jsoncons/json.hpp +18 -0
  37. data/lib/jsoncons/jsoncons/include/jsoncons/json_array.hpp +324 -0
  38. data/lib/jsoncons/jsoncons/include/jsoncons/json_content_handler.hpp +12 -0
  39. data/lib/jsoncons/jsoncons/include/jsoncons/json_cursor.hpp +448 -0
  40. data/lib/jsoncons/jsoncons/include/jsoncons/json_decoder.hpp +420 -0
  41. data/lib/jsoncons/jsoncons/include/jsoncons/json_encoder.hpp +1587 -0
  42. data/lib/jsoncons/jsoncons/include/jsoncons/json_error.hpp +156 -0
  43. data/lib/jsoncons/jsoncons/include/jsoncons/json_exception.hpp +241 -0
  44. data/lib/jsoncons/jsoncons/include/jsoncons/json_filter.hpp +653 -0
  45. data/lib/jsoncons/jsoncons/include/jsoncons/json_fwd.hpp +23 -0
  46. data/lib/jsoncons/jsoncons/include/jsoncons/json_object.hpp +1772 -0
  47. data/lib/jsoncons/jsoncons/include/jsoncons/json_options.hpp +862 -0
  48. data/lib/jsoncons/jsoncons/include/jsoncons/json_parser.hpp +2900 -0
  49. data/lib/jsoncons/jsoncons/include/jsoncons/json_reader.hpp +731 -0
  50. data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros.hpp +1072 -0
  51. data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros_deprecated.hpp +144 -0
  52. data/lib/jsoncons/jsoncons/include/jsoncons/json_type.hpp +206 -0
  53. data/lib/jsoncons/jsoncons/include/jsoncons/json_type_traits.hpp +1830 -0
  54. data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor.hpp +1560 -0
  55. data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor2.hpp +2079 -0
  56. data/lib/jsoncons/jsoncons/include/jsoncons/pretty_print.hpp +89 -0
  57. data/lib/jsoncons/jsoncons/include/jsoncons/ser_context.hpp +62 -0
  58. data/lib/jsoncons/jsoncons/include/jsoncons/sink.hpp +289 -0
  59. data/lib/jsoncons/jsoncons/include/jsoncons/source.hpp +777 -0
  60. data/lib/jsoncons/jsoncons/include/jsoncons/source_adaptor.hpp +148 -0
  61. data/lib/jsoncons/jsoncons/include/jsoncons/staj2_cursor.hpp +1189 -0
  62. data/lib/jsoncons/jsoncons/include/jsoncons/staj_cursor.hpp +1254 -0
  63. data/lib/jsoncons/jsoncons/include/jsoncons/staj_iterator.hpp +449 -0
  64. data/lib/jsoncons/jsoncons/include/jsoncons/tag_type.hpp +245 -0
  65. data/lib/jsoncons/jsoncons/include/jsoncons/text_source_adaptor.hpp +144 -0
  66. data/lib/jsoncons/jsoncons/include/jsoncons/traits_extension.hpp +884 -0
  67. data/lib/jsoncons/jsoncons/include/jsoncons/typed_array_view.hpp +250 -0
  68. data/lib/jsoncons/jsoncons/include/jsoncons/unicode_traits.hpp +1330 -0
  69. data/lib/jsoncons/jsoncons/include/jsoncons/uri.hpp +635 -0
  70. data/lib/jsoncons/jsoncons/include/jsoncons/value_converter.hpp +340 -0
  71. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson.hpp +23 -0
  72. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_cursor.hpp +320 -0
  73. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_decimal128.hpp +865 -0
  74. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_encoder.hpp +585 -0
  75. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_error.hpp +103 -0
  76. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_oid.hpp +245 -0
  77. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_options.hpp +75 -0
  78. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_parser.hpp +645 -0
  79. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_reader.hpp +92 -0
  80. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_type.hpp +44 -0
  81. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/decode_bson.hpp +201 -0
  82. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/encode_bson.hpp +144 -0
  83. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor.hpp +26 -0
  84. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor.hpp +351 -0
  85. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor2.hpp +265 -0
  86. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_detail.hpp +93 -0
  87. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_encoder.hpp +1766 -0
  88. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_error.hpp +105 -0
  89. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_options.hpp +113 -0
  90. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_parser.hpp +1942 -0
  91. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_reader.hpp +116 -0
  92. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/decode_cbor.hpp +203 -0
  93. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/encode_cbor.hpp +151 -0
  94. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv.hpp +17 -0
  95. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_cursor.hpp +358 -0
  96. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_encoder.hpp +954 -0
  97. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_error.hpp +85 -0
  98. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_options.hpp +973 -0
  99. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_parser.hpp +2099 -0
  100. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_reader.hpp +348 -0
  101. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_serializer.hpp +12 -0
  102. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/decode_csv.hpp +208 -0
  103. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/encode_csv.hpp +122 -0
  104. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath.hpp +5215 -0
  105. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath_error.hpp +215 -0
  106. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch.hpp +579 -0
  107. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch_error.hpp +121 -0
  108. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/expression.hpp +3329 -0
  109. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/flatten.hpp +432 -0
  110. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_location.hpp +445 -0
  111. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_query.hpp +115 -0
  112. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath.hpp +13 -0
  113. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_error.hpp +240 -0
  114. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_expression.hpp +2612 -0
  115. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp +1322 -0
  116. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer.hpp +1577 -0
  117. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer_error.hpp +119 -0
  118. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/format_validator.hpp +968 -0
  119. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/json_validator.hpp +120 -0
  120. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema.hpp +13 -0
  121. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_error.hpp +105 -0
  122. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_version.hpp +18 -0
  123. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator.hpp +1745 -0
  124. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator_factory.hpp +556 -0
  125. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_draft7.hpp +198 -0
  126. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_location.hpp +200 -0
  127. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_version.hpp +35 -0
  128. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/subschema.hpp +144 -0
  129. data/lib/jsoncons/jsoncons/include/jsoncons_ext/mergepatch/mergepatch.hpp +103 -0
  130. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/decode_msgpack.hpp +202 -0
  131. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/encode_msgpack.hpp +142 -0
  132. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack.hpp +24 -0
  133. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor.hpp +343 -0
  134. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor2.hpp +259 -0
  135. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_encoder.hpp +753 -0
  136. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_error.hpp +94 -0
  137. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_options.hpp +74 -0
  138. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_parser.hpp +748 -0
  139. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_reader.hpp +116 -0
  140. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_type.hpp +63 -0
  141. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/decode_ubjson.hpp +201 -0
  142. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/encode_ubjson.hpp +142 -0
  143. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson.hpp +23 -0
  144. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_cursor.hpp +307 -0
  145. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_encoder.hpp +502 -0
  146. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_error.hpp +100 -0
  147. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_options.hpp +87 -0
  148. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_parser.hpp +880 -0
  149. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_reader.hpp +92 -0
  150. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_type.hpp +43 -0
  151. data/lib/jsoncons/version.rb +5 -0
  152. data/lib/jsoncons.rb +33 -0
  153. data/test/jsoncons_test.rb +108 -0
  154. data/test/test_helper.rb +7 -0
  155. metadata +268 -0
@@ -0,0 +1,2612 @@
1
+ // Copyright 2021 Daniel Parker
2
+ // Distributed under the Boost license, Version 1.0.
3
+ // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
+
5
+ // See https://github.com/danielaparker/jsoncons for latest version
6
+
7
+ #ifndef JSONCONS_JSONPATH_JSONPATH_EXPRESSION_HPP
8
+ #define JSONCONS_JSONPATH_JSONPATH_EXPRESSION_HPP
9
+
10
+ #include <string>
11
+ #include <vector>
12
+ #include <memory>
13
+ #include <type_traits> // std::is_const
14
+ #include <limits> // std::numeric_limits
15
+ #include <utility> // std::move
16
+ #include <regex>
17
+ #include <algorithm> // std::reverse
18
+ #include <jsoncons/json.hpp>
19
+ #include <jsoncons_ext/jsonpath/jsonpath_error.hpp>
20
+ #include <jsoncons_ext/jsonpath/expression.hpp>
21
+ #include <jsoncons_ext/jsonpath/jsonpath_selector.hpp>
22
+
23
+ namespace jsoncons {
24
+ namespace jsonpath {
25
+ namespace detail {
26
+
27
+ enum class path_state
28
+ {
29
+ start,
30
+ root_or_current_node,
31
+ expect_function_expr,
32
+ relative_path,
33
+ relative_location,
34
+ parent_operator,
35
+ ancestor_depth,
36
+ filter_expression,
37
+ expression_rhs,
38
+ recursive_descent_or_expression_lhs,
39
+ path_or_literal_or_function,
40
+ json_text_or_function,
41
+ json_text_or_function_name,
42
+ json_text_string,
43
+ json_value,
44
+ json_string,
45
+ identifier_or_function_expr,
46
+ name_or_lbracket,
47
+ unquoted_string,
48
+ anything,
49
+ number,
50
+ function_expression,
51
+ argument,
52
+ zero_or_one_arguments,
53
+ one_or_more_arguments,
54
+ identifier,
55
+ single_quoted_string,
56
+ double_quoted_string,
57
+ bracketed_unquoted_name_or_union,
58
+ union_expression,
59
+ identifier_or_union,
60
+ bracket_specifier_or_union,
61
+ bracketed_wildcard,
62
+ index_or_slice,
63
+ wildcard_or_union,
64
+ union_element,
65
+ index_or_slice_or_union,
66
+ integer,
67
+ digit,
68
+ slice_expression_stop,
69
+ slice_expression_step,
70
+ comma_or_rbracket,
71
+ expect_rparen,
72
+ expect_rbracket,
73
+ quoted_string_escape_char,
74
+ escape_u1,
75
+ escape_u2,
76
+ escape_u3,
77
+ escape_u4,
78
+ escape_expect_surrogate_pair1,
79
+ escape_expect_surrogate_pair2,
80
+ escape_u5,
81
+ escape_u6,
82
+ escape_u7,
83
+ escape_u8,
84
+ expression,
85
+ comparator_expression,
86
+ eq_or_regex,
87
+ expect_regex,
88
+ regex,
89
+ regex_options,
90
+ regex_pattern,
91
+ cmp_lt_or_lte,
92
+ cmp_gt_or_gte,
93
+ cmp_ne,
94
+ expect_or,
95
+ expect_and
96
+ };
97
+
98
+ template<class Json,
99
+ class JsonReference>
100
+ class jsonpath_evaluator : public ser_context
101
+ {
102
+ public:
103
+ using char_type = typename Json::char_type;
104
+ using string_type = std::basic_string<char_type,std::char_traits<char_type>>;
105
+ using string_view_type = typename Json::string_view_type;
106
+ using path_value_pair_type = path_value_pair<Json,JsonReference>;
107
+ using value_type = Json;
108
+ using reference = JsonReference;
109
+ using pointer = typename path_value_pair_type::value_pointer;
110
+ using token_type = token<Json,JsonReference>;
111
+ using path_expression_type = path_expression<Json,JsonReference>;
112
+ using expression_type = expression<Json,JsonReference>;
113
+ using json_location_type = json_location<char_type>;
114
+ using json_location_node_type = json_location_node<char_type>;
115
+ using selector_type = jsonpath_selector<Json,JsonReference>;
116
+
117
+ private:
118
+
119
+ std::size_t line_;
120
+ std::size_t column_;
121
+ const char_type* begin_input_;
122
+ const char_type* end_input_;
123
+ const char_type* p_;
124
+
125
+ using argument_type = std::vector<pointer>;
126
+ std::vector<argument_type> function_stack_;
127
+ std::vector<path_state> state_stack_;
128
+ std::vector<token_type> output_stack_;
129
+ std::vector<token_type> operator_stack_;
130
+
131
+ public:
132
+ jsonpath_evaluator()
133
+ : line_(1), column_(1),
134
+ begin_input_(nullptr), end_input_(nullptr),
135
+ p_(nullptr)
136
+ {
137
+ }
138
+
139
+ jsonpath_evaluator(std::size_t line, std::size_t column)
140
+ : line_(line), column_(column),
141
+ begin_input_(nullptr), end_input_(nullptr),
142
+ p_(nullptr)
143
+ {
144
+ }
145
+
146
+ std::size_t line() const
147
+ {
148
+ return line_;
149
+ }
150
+
151
+ std::size_t column() const
152
+ {
153
+ return column_;
154
+ }
155
+
156
+ path_expression_type compile(static_resources<value_type,reference>& resources, const string_view_type& path)
157
+ {
158
+ std::error_code ec;
159
+ auto result = compile(resources, path, ec);
160
+ if (ec)
161
+ {
162
+ JSONCONS_THROW(jsonpath_error(ec, line_, column_));
163
+ }
164
+ return result;
165
+ }
166
+
167
+ path_expression_type compile(static_resources<value_type,reference>& resources,
168
+ const string_view_type& path,
169
+ std::error_code& ec)
170
+ {
171
+ std::size_t selector_id = 0;
172
+
173
+ string_type buffer;
174
+ string_type buffer2;
175
+ uint32_t cp = 0;
176
+ uint32_t cp2 = 0;
177
+
178
+ begin_input_ = path.data();
179
+ end_input_ = path.data() + path.length();
180
+ p_ = begin_input_;
181
+
182
+ slice slic;
183
+ bool paths_required = false;
184
+ int ancestor_depth = 0;
185
+
186
+ state_stack_.emplace_back(path_state::start);
187
+ while (p_ < end_input_ && !state_stack_.empty())
188
+ {
189
+ switch (state_stack_.back())
190
+ {
191
+ case path_state::start:
192
+ {
193
+ switch (*p_)
194
+ {
195
+ case ' ':case '\t':case '\r':case '\n':
196
+ advance_past_space_character();
197
+ break;
198
+ case '$':
199
+ case '@':
200
+ {
201
+ push_token(resources, token_type(resources.new_selector(current_node_selector<Json,JsonReference>())), ec);
202
+ if (ec) {return path_expression_type();}
203
+ state_stack_.emplace_back(path_state::relative_location);
204
+ ++p_;
205
+ ++column_;
206
+ break;
207
+ }
208
+ default:
209
+ {
210
+ state_stack_.emplace_back(path_state::relative_location);
211
+ state_stack_.emplace_back(path_state::expect_function_expr);
212
+ state_stack_.emplace_back(path_state::unquoted_string);
213
+ break;
214
+ }
215
+ }
216
+ break;
217
+ }
218
+ case path_state::root_or_current_node:
219
+ switch (*p_)
220
+ {
221
+ case ' ':case '\t':case '\r':case '\n':
222
+ advance_past_space_character();
223
+ break;
224
+ case '$':
225
+ push_token(resources, token_type(root_node_arg), ec);
226
+ push_token(resources, token_type(resources.new_selector(root_selector<Json,JsonReference>(selector_id++))), ec);
227
+ if (ec) {return path_expression_type();}
228
+ state_stack_.pop_back();
229
+ ++p_;
230
+ ++column_;
231
+ break;
232
+ case '@':
233
+ push_token(resources, token_type(current_node_arg), ec); // ISSUE
234
+ push_token(resources, token_type(resources.new_selector(current_node_selector<Json,JsonReference>())), ec);
235
+ if (ec) {return path_expression_type();}
236
+ state_stack_.pop_back();
237
+ ++p_;
238
+ ++column_;
239
+ break;
240
+ default:
241
+ ec = jsonpath_errc::syntax_error;
242
+ return path_expression_type();
243
+ }
244
+ break;
245
+ case path_state::recursive_descent_or_expression_lhs:
246
+ switch (*p_)
247
+ {
248
+ case '.':
249
+ push_token(resources, token_type(resources.new_selector(recursive_selector<Json,JsonReference>())), ec);
250
+ if (ec) {return path_expression_type();}
251
+ ++p_;
252
+ ++column_;
253
+ state_stack_.back() = path_state::name_or_lbracket;
254
+ break;
255
+ default:
256
+ state_stack_.back() = path_state::relative_path;
257
+ break;
258
+ }
259
+ break;
260
+ case path_state::name_or_lbracket:
261
+ switch (*p_)
262
+ {
263
+ case ' ':case '\t':case '\r':case '\n':
264
+ advance_past_space_character();
265
+ break;
266
+ case '[': // [ can follow ..
267
+ state_stack_.back() = path_state::bracket_specifier_or_union;
268
+ ++p_;
269
+ ++column_;
270
+ break;
271
+ default:
272
+ buffer.clear();
273
+ state_stack_.back() = path_state::relative_path;
274
+ break;
275
+ }
276
+ break;
277
+ case path_state::json_string:
278
+ {
279
+ //std::cout << "literal: " << buffer << "\n";
280
+ push_token(resources, token_type(literal_arg, Json(buffer)), ec);
281
+ if (ec) {return path_expression_type();}
282
+ buffer.clear();
283
+ state_stack_.pop_back(); // json_value
284
+ break;
285
+ }
286
+ case path_state::path_or_literal_or_function:
287
+ {
288
+ switch (*p_)
289
+ {
290
+ case ' ':case '\t':case '\r':case '\n':
291
+ advance_past_space_character();
292
+ break;
293
+ case '$':
294
+ case '@':
295
+ state_stack_.back() = path_state::relative_location;
296
+ state_stack_.push_back(path_state::root_or_current_node);
297
+ break;
298
+ case '(':
299
+ {
300
+ ++p_;
301
+ ++column_;
302
+ push_token(resources, lparen_arg, ec);
303
+ if (ec) {return path_expression_type();}
304
+ state_stack_.back() = path_state::expect_rparen;
305
+ state_stack_.emplace_back(path_state::expression_rhs);
306
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
307
+ break;
308
+ }
309
+ case '\'':
310
+ state_stack_.back() = path_state::json_string;
311
+ state_stack_.emplace_back(path_state::single_quoted_string);
312
+ ++p_;
313
+ ++column_;
314
+ break;
315
+ case '\"':
316
+ state_stack_.back() = path_state::json_string;
317
+ state_stack_.emplace_back(path_state::double_quoted_string);
318
+ ++p_;
319
+ ++column_;
320
+ break;
321
+ case '!':
322
+ {
323
+ ++p_;
324
+ ++column_;
325
+ push_token(resources, token_type(resources.get_unary_not()), ec);
326
+ if (ec) {return path_expression_type();}
327
+ break;
328
+ }
329
+ case '-':
330
+ {
331
+ ++p_;
332
+ ++column_;
333
+ push_token(resources, token_type(resources.get_unary_minus()), ec);
334
+ if (ec) {return path_expression_type();}
335
+ break;
336
+ }
337
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
338
+ {
339
+ state_stack_.back() = path_state::json_value;
340
+ state_stack_.emplace_back(path_state::number);
341
+ break;
342
+ }
343
+ default:
344
+ {
345
+ state_stack_.back() = path_state::json_text_or_function_name;
346
+ break;
347
+ }
348
+ }
349
+ break;
350
+ }
351
+ case path_state::json_text_or_function:
352
+ {
353
+ switch(*p_)
354
+ {
355
+ case '(':
356
+ {
357
+ auto f = resources.get_function(buffer, ec);
358
+ if (ec)
359
+ {
360
+ return path_expression_type();
361
+ }
362
+ buffer.clear();
363
+ push_token(resources, current_node_arg, ec);
364
+ if (ec) {return path_expression_type();}
365
+ push_token(resources, token_type(f), ec);
366
+ if (ec) {return path_expression_type();}
367
+ state_stack_.back() = path_state::function_expression;
368
+ state_stack_.emplace_back(path_state::zero_or_one_arguments);
369
+ ++p_;
370
+ ++column_;
371
+ break;
372
+ }
373
+ default:
374
+ {
375
+ json_decoder<Json> decoder;
376
+ basic_json_parser<char_type> parser;
377
+ parser.update(buffer.data(),buffer.size());
378
+ parser.parse_some(decoder, ec);
379
+ if (ec)
380
+ {
381
+ return path_expression_type();
382
+ }
383
+ parser.finish_parse(decoder, ec);
384
+ if (ec)
385
+ {
386
+ return path_expression_type();
387
+ }
388
+ push_token(resources, token_type(literal_arg, decoder.get_result()), ec);
389
+ if (ec) {return path_expression_type();}
390
+ buffer.clear();
391
+ state_stack_.pop_back();
392
+ break;
393
+ }
394
+ }
395
+ break;
396
+ }
397
+ case path_state::json_value:
398
+ {
399
+ json_decoder<Json> decoder;
400
+ basic_json_parser<char_type> parser;
401
+ parser.update(buffer.data(),buffer.size());
402
+ parser.parse_some(decoder, ec);
403
+ if (ec)
404
+ {
405
+ return path_expression_type();
406
+ }
407
+ parser.finish_parse(decoder, ec);
408
+ if (ec)
409
+ {
410
+ return path_expression_type();
411
+ }
412
+ push_token(resources, token_type(literal_arg, decoder.get_result()), ec);
413
+ if (ec) {return path_expression_type();}
414
+ buffer.clear();
415
+ state_stack_.pop_back();
416
+ break;
417
+ }
418
+ case path_state::json_text_or_function_name:
419
+ switch (*p_)
420
+ {
421
+ case ' ':case '\t':case '\r':case '\n':
422
+ advance_past_space_character();
423
+ break;
424
+ case '{':
425
+ case '[':
426
+ {
427
+ json_decoder<Json> decoder;
428
+ basic_json_parser<char_type> parser;
429
+ parser.update(p_,end_input_ - p_);
430
+ parser.parse_some(decoder, ec);
431
+ if (ec)
432
+ {
433
+ return path_expression_type();
434
+ }
435
+ parser.finish_parse(decoder, ec);
436
+ if (ec)
437
+ {
438
+ return path_expression_type();
439
+ }
440
+ push_token(resources, token_type(literal_arg, decoder.get_result()), ec);
441
+ if (ec) {return path_expression_type();}
442
+ buffer.clear();
443
+ state_stack_.pop_back();
444
+ p_ = parser.current();
445
+ column_ = column_ + parser.column() - 1;
446
+ break;
447
+ }
448
+ case '-':case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
449
+ state_stack_.back() = path_state::json_text_or_function;
450
+ state_stack_.emplace_back(path_state::number);
451
+ buffer.push_back(*p_);
452
+ ++p_;
453
+ ++column_;
454
+ break;
455
+ case '\"':
456
+ state_stack_.back() = path_state::json_text_or_function;
457
+ state_stack_.emplace_back(path_state::json_text_string);
458
+ buffer.push_back(*p_);
459
+ ++p_;
460
+ ++column_;
461
+ break;
462
+ default:
463
+ state_stack_.back() = path_state::json_text_or_function;
464
+ state_stack_.emplace_back(path_state::unquoted_string);
465
+ buffer.push_back(*p_);
466
+ ++p_;
467
+ ++column_;
468
+ break;
469
+ };
470
+ break;
471
+ case path_state::number:
472
+ switch (*p_)
473
+ {
474
+ case '-':case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
475
+ case 'e':case 'E':case '.':
476
+ buffer.push_back(*p_);
477
+ ++p_;
478
+ ++column_;
479
+ break;
480
+ default:
481
+ state_stack_.pop_back(); // number
482
+ break;
483
+ };
484
+ break;
485
+ case path_state::json_text_string:
486
+ switch (*p_)
487
+ {
488
+ case '\\':
489
+ buffer.push_back(*p_);
490
+ ++p_;
491
+ ++column_;
492
+ if (p_ == end_input_)
493
+ {
494
+ ec = jsonpath_errc::unexpected_eof;
495
+ return path_expression_type();
496
+ }
497
+ buffer.push_back(*p_);
498
+ ++p_;
499
+ ++column_;
500
+ break;
501
+ case '\"':
502
+ buffer.push_back(*p_);
503
+ state_stack_.pop_back();
504
+ ++p_;
505
+ ++column_;
506
+ break;
507
+ default:
508
+ buffer.push_back(*p_);
509
+ ++p_;
510
+ ++column_;
511
+ break;
512
+ };
513
+ break;
514
+ case path_state::relative_path:
515
+ switch (*p_)
516
+ {
517
+ case ' ':case '\t':case '\r':case '\n':
518
+ advance_past_space_character();
519
+ break;
520
+ case '*':
521
+ push_token(resources, token_type(resources.new_selector(wildcard_selector<Json,JsonReference>())), ec);
522
+ if (ec) {return path_expression_type();}
523
+ state_stack_.pop_back();
524
+ ++p_;
525
+ ++column_;
526
+ break;
527
+ case '\'':
528
+ state_stack_.back() = path_state::identifier;
529
+ state_stack_.emplace_back(path_state::single_quoted_string);
530
+ ++p_;
531
+ ++column_;
532
+ break;
533
+ case '\"':
534
+ state_stack_.back() = path_state::identifier;
535
+ state_stack_.emplace_back(path_state::double_quoted_string);
536
+ ++p_;
537
+ ++column_;
538
+ break;
539
+ case '[':
540
+ case '.':
541
+ ec = jsonpath_errc::expected_relative_path;
542
+ return path_expression_type();
543
+ default:
544
+ buffer.clear();
545
+ state_stack_.back() = path_state::identifier_or_function_expr;
546
+ state_stack_.emplace_back(path_state::unquoted_string);
547
+ break;
548
+ }
549
+ break;
550
+ case path_state::identifier_or_function_expr:
551
+ {
552
+ switch(*p_)
553
+ {
554
+ case ' ':case '\t':case '\r':case '\n':
555
+ advance_past_space_character();
556
+ break;
557
+ case '(':
558
+ {
559
+ auto f = resources.get_function(buffer, ec);
560
+ if (ec)
561
+ {
562
+ return path_expression_type();
563
+ }
564
+ buffer.clear();
565
+ push_token(resources, current_node_arg, ec);
566
+ push_token(resources, token_type(f), ec);
567
+ if (ec) {return path_expression_type();}
568
+ state_stack_.back() = path_state::function_expression;
569
+ state_stack_.emplace_back(path_state::zero_or_one_arguments);
570
+ ++p_;
571
+ ++column_;
572
+ break;
573
+ }
574
+ default:
575
+ {
576
+ push_token(resources, token_type(resources.new_selector(identifier_selector<Json,JsonReference>(buffer))), ec);
577
+ if (ec) {return path_expression_type();}
578
+ buffer.clear();
579
+ state_stack_.pop_back();
580
+ break;
581
+ }
582
+ }
583
+ break;
584
+ }
585
+ case path_state::expect_function_expr:
586
+ {
587
+ switch(*p_)
588
+ {
589
+ case ' ':case '\t':case '\r':case '\n':
590
+ advance_past_space_character();
591
+ break;
592
+ case '(':
593
+ {
594
+ auto f = resources.get_function(buffer, ec);
595
+ if (ec)
596
+ {
597
+ return path_expression_type();
598
+ }
599
+ buffer.clear();
600
+ push_token(resources, current_node_arg, ec);
601
+ push_token(resources, token_type(f), ec);
602
+ if (ec) {return path_expression_type();}
603
+ state_stack_.back() = path_state::function_expression;
604
+ state_stack_.emplace_back(path_state::zero_or_one_arguments);
605
+ ++p_;
606
+ ++column_;
607
+ break;
608
+ }
609
+ default:
610
+ {
611
+ ec = jsonpath_errc::expected_root_or_function;
612
+ return path_expression_type();
613
+ }
614
+ }
615
+ break;
616
+ }
617
+ case path_state::function_expression:
618
+ {
619
+
620
+ switch (*p_)
621
+ {
622
+ case ' ':case '\t':case '\r':case '\n':
623
+ advance_past_space_character();
624
+ break;
625
+ case ',':
626
+ push_token(resources, token_type(current_node_arg), ec);
627
+ if (ec) {return path_expression_type();}
628
+ push_token(resources, token_type(begin_expression_arg), ec);
629
+ if (ec) {return path_expression_type();}
630
+ if (ec) {return path_expression_type();}
631
+ state_stack_.emplace_back(path_state::argument);
632
+ state_stack_.emplace_back(path_state::expression_rhs);
633
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
634
+ ++p_;
635
+ ++column_;
636
+ break;
637
+ case ')':
638
+ {
639
+ push_token(resources, token_type(end_function_arg), ec);
640
+ if (ec) {return path_expression_type();}
641
+ state_stack_.pop_back();
642
+ ++p_;
643
+ ++column_;
644
+ break;
645
+ }
646
+ default:
647
+ ec = jsonpath_errc::syntax_error;
648
+ return path_expression_type();
649
+ }
650
+ break;
651
+ }
652
+ case path_state::zero_or_one_arguments:
653
+ {
654
+ switch (*p_)
655
+ {
656
+ case ' ':case '\t':case '\r':case '\n':
657
+ advance_past_space_character();
658
+ break;
659
+ case ')':
660
+ state_stack_.pop_back();
661
+ break;
662
+ default:
663
+ push_token(resources, token_type(begin_expression_arg), ec);
664
+ if (ec) {return path_expression_type();}
665
+ state_stack_.back() = path_state::one_or_more_arguments;
666
+ state_stack_.emplace_back(path_state::argument);
667
+ state_stack_.emplace_back(path_state::expression_rhs);
668
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
669
+ break;
670
+ }
671
+ break;
672
+ }
673
+ case path_state::one_or_more_arguments:
674
+ {
675
+ switch (*p_)
676
+ {
677
+ case ' ':case '\t':case '\r':case '\n':
678
+ advance_past_space_character();
679
+ break;
680
+ case ')':
681
+ state_stack_.pop_back();
682
+ break;
683
+ case ',':
684
+ push_token(resources, token_type(begin_expression_arg), ec);
685
+ if (ec) {return path_expression_type();}
686
+ state_stack_.emplace_back(path_state::argument);
687
+ state_stack_.emplace_back(path_state::expression_rhs);
688
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
689
+ ++p_;
690
+ ++column_;
691
+ break;
692
+ }
693
+ break;
694
+ }
695
+ case path_state::argument:
696
+ {
697
+ switch(*p_)
698
+ {
699
+ case ' ':case '\t':case '\r':case '\n':
700
+ advance_past_space_character();
701
+ break;
702
+ case ',':
703
+ case ')':
704
+ {
705
+ push_token(resources, token_type(end_argument_expression_arg), ec);
706
+ push_token(resources, argument_arg, ec);
707
+ //push_token(resources, argument_arg, ec);
708
+ if (ec) {return path_expression_type();}
709
+ state_stack_.pop_back();
710
+ break;
711
+ }
712
+ default:
713
+ ec = jsonpath_errc::expected_comma_or_rparen;
714
+ return path_expression_type();
715
+ }
716
+ break;
717
+ }
718
+ case path_state::unquoted_string:
719
+ switch (*p_)
720
+ {
721
+ case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'g':case 'h':case 'i':case 'j':case 'k':case 'l':case 'm':case 'n':case 'o':case 'p':case 'q':case 'r':case 's':case 't':case 'u':case 'v':case 'w':case 'x':case 'y':case 'z':
722
+ case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':case 'G':case 'H':case 'I':case 'J':case 'K':case 'L':case 'M':case 'N':case 'O':case 'P':case 'Q':case 'R':case 'S':case 'T':case 'U':case 'V':case 'W':case 'X':case 'Y':case 'Z':
723
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
724
+ case '_':
725
+ buffer.push_back(*p_);
726
+ ++p_;
727
+ ++column_;
728
+ break;
729
+ default:
730
+ if (typename std::make_unsigned<char_type>::type(*p_) > 127)
731
+ {
732
+ buffer.push_back(*p_);
733
+ ++p_;
734
+ ++column_;
735
+ }
736
+ else
737
+ {
738
+ state_stack_.pop_back(); // unquoted_string
739
+ }
740
+ break;
741
+ };
742
+ break;
743
+ case path_state::relative_location:
744
+ switch (*p_)
745
+ {
746
+ case ' ':case '\t':case '\r':case '\n':
747
+ advance_past_space_character();
748
+ break;
749
+ case '.':
750
+ state_stack_.emplace_back(path_state::recursive_descent_or_expression_lhs);
751
+ ++p_;
752
+ ++column_;
753
+ break;
754
+ case '[':
755
+ state_stack_.emplace_back(path_state::bracket_specifier_or_union);
756
+ ++p_;
757
+ ++column_;
758
+ break;
759
+ case '^':
760
+ ancestor_depth = 0;
761
+ state_stack_.emplace_back(path_state::parent_operator);
762
+ state_stack_.emplace_back(path_state::ancestor_depth);
763
+ break;
764
+ default:
765
+ state_stack_.pop_back();
766
+ break;
767
+ };
768
+ break;
769
+ case path_state::parent_operator:
770
+ {
771
+ push_token(resources, token_type(resources.new_selector(parent_node_selector<Json,JsonReference>(ancestor_depth))), ec);
772
+ paths_required = true;
773
+ ancestor_depth = 0;
774
+ ++p_;
775
+ ++column_;
776
+ state_stack_.pop_back();
777
+ break;
778
+ }
779
+ case path_state::ancestor_depth:
780
+ {
781
+ switch (*p_)
782
+ {
783
+ case ' ':case '\t':case '\r':case '\n':
784
+ advance_past_space_character();
785
+ break;
786
+ case '^':
787
+ {
788
+ ++ancestor_depth;
789
+ ++p_;
790
+ ++column_;
791
+ break;
792
+ }
793
+ default:
794
+ {
795
+ state_stack_.pop_back();
796
+ break;
797
+ }
798
+ }
799
+ break;
800
+ }
801
+ case path_state::expression_rhs:
802
+ switch (*p_)
803
+ {
804
+ case ' ':case '\t':case '\r':case '\n':
805
+ advance_past_space_character();
806
+ break;
807
+ case '.':
808
+ state_stack_.emplace_back(path_state::recursive_descent_or_expression_lhs);
809
+ ++p_;
810
+ ++column_;
811
+ break;
812
+ case '[':
813
+ state_stack_.emplace_back(path_state::bracket_specifier_or_union);
814
+ ++p_;
815
+ ++column_;
816
+ break;
817
+ case ')':
818
+ {
819
+ state_stack_.pop_back();
820
+ break;
821
+ }
822
+ case '|':
823
+ ++p_;
824
+ ++column_;
825
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
826
+ state_stack_.emplace_back(path_state::expect_or);
827
+ break;
828
+ case '&':
829
+ ++p_;
830
+ ++column_;
831
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
832
+ state_stack_.emplace_back(path_state::expect_and);
833
+ break;
834
+ case '<':
835
+ case '>':
836
+ {
837
+ state_stack_.emplace_back(path_state::comparator_expression);
838
+ break;
839
+ }
840
+ case '=':
841
+ {
842
+ state_stack_.emplace_back(path_state::eq_or_regex);
843
+ ++p_;
844
+ ++column_;
845
+ break;
846
+ }
847
+ case '!':
848
+ {
849
+ ++p_;
850
+ ++column_;
851
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
852
+ state_stack_.emplace_back(path_state::cmp_ne);
853
+ break;
854
+ }
855
+ case '+':
856
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
857
+ push_token(resources, token_type(resources.get_plus_operator()), ec);
858
+ if (ec) {return path_expression_type();}
859
+ ++p_;
860
+ ++column_;
861
+ break;
862
+ case '-':
863
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
864
+ push_token(resources, token_type(resources.get_minus_operator()), ec);
865
+ if (ec) {return path_expression_type();}
866
+ ++p_;
867
+ ++column_;
868
+ break;
869
+ case '*':
870
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
871
+ push_token(resources, token_type(resources.get_mult_operator()), ec);
872
+ if (ec) {return path_expression_type();}
873
+ ++p_;
874
+ ++column_;
875
+ break;
876
+ case '/':
877
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
878
+ push_token(resources, token_type(resources.get_div_operator()), ec);
879
+ if (ec) {return path_expression_type();}
880
+ ++p_;
881
+ ++column_;
882
+ break;
883
+ case '%':
884
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
885
+ push_token(resources, token_type(resources.get_modulus_operator()), ec);
886
+ if (ec) {return path_expression_type();}
887
+ ++p_;
888
+ ++column_;
889
+ break;
890
+ case ']':
891
+ case ',':
892
+ state_stack_.pop_back();
893
+ break;
894
+ default:
895
+ ec = jsonpath_errc::expected_separator;
896
+ return path_expression_type();
897
+ };
898
+ break;
899
+ case path_state::expect_or:
900
+ {
901
+ switch (*p_)
902
+ {
903
+ case '|':
904
+ push_token(resources, token_type(resources.get_or_operator()), ec);
905
+ if (ec) {return path_expression_type();}
906
+ state_stack_.pop_back();
907
+ ++p_;
908
+ ++column_;
909
+ break;
910
+ default:
911
+ ec = jsonpath_errc::expected_or;
912
+ return path_expression_type();
913
+ }
914
+ break;
915
+ }
916
+ case path_state::expect_and:
917
+ {
918
+ switch(*p_)
919
+ {
920
+ case '&':
921
+ push_token(resources, token_type(resources.get_and_operator()), ec);
922
+ if (ec) {return path_expression_type();}
923
+ state_stack_.pop_back(); // expect_and
924
+ ++p_;
925
+ ++column_;
926
+ break;
927
+ default:
928
+ ec = jsonpath_errc::expected_and;
929
+ return path_expression_type();
930
+ }
931
+ break;
932
+ }
933
+ case path_state::comparator_expression:
934
+ switch(*p_)
935
+ {
936
+ case ' ':case '\t':case '\r':case '\n':
937
+ advance_past_space_character();
938
+ break;
939
+ case '<':
940
+ ++p_;
941
+ ++column_;
942
+ state_stack_.back() = path_state::path_or_literal_or_function;
943
+ state_stack_.emplace_back(path_state::cmp_lt_or_lte);
944
+ break;
945
+ case '>':
946
+ ++p_;
947
+ ++column_;
948
+ state_stack_.back() = path_state::path_or_literal_or_function;
949
+ state_stack_.emplace_back(path_state::cmp_gt_or_gte);
950
+ break;
951
+ default:
952
+ if (state_stack_.size() > 1)
953
+ {
954
+ state_stack_.pop_back();
955
+ }
956
+ else
957
+ {
958
+ ec = jsonpath_errc::syntax_error;
959
+ return path_expression_type();
960
+ }
961
+ break;
962
+ }
963
+ break;
964
+ case path_state::eq_or_regex:
965
+ switch(*p_)
966
+ {
967
+ case ' ':case '\t':case '\r':case '\n':
968
+ advance_past_space_character();
969
+ break;
970
+ case '=':
971
+ {
972
+ push_token(resources, token_type(resources.get_eq_operator()), ec);
973
+ if (ec) {return path_expression_type();}
974
+ state_stack_.back() = path_state::path_or_literal_or_function;
975
+ ++p_;
976
+ ++column_;
977
+ break;
978
+ }
979
+ case '~':
980
+ {
981
+ ++p_;
982
+ ++column_;
983
+ state_stack_.emplace_back(path_state::expect_regex);
984
+ break;
985
+ }
986
+ default:
987
+ if (state_stack_.size() > 1)
988
+ {
989
+ state_stack_.pop_back();
990
+ }
991
+ else
992
+ {
993
+ ec = jsonpath_errc::syntax_error;
994
+ return path_expression_type();
995
+ }
996
+ break;
997
+ }
998
+ break;
999
+ case path_state::expect_regex:
1000
+ switch (*p_)
1001
+ {
1002
+ case ' ':case '\t':case '\r':case '\n':
1003
+ advance_past_space_character();
1004
+ break;
1005
+ case '/':
1006
+ state_stack_.back() = path_state::regex;
1007
+ state_stack_.emplace_back(path_state::regex_options);
1008
+ state_stack_.emplace_back(path_state::regex_pattern);
1009
+ ++p_;
1010
+ ++column_;
1011
+ break;
1012
+ default:
1013
+ ec = jsonpath_errc::expected_forward_slash;
1014
+ return path_expression_type();
1015
+ };
1016
+ break;
1017
+ case path_state::regex:
1018
+ {
1019
+ std::regex::flag_type options = std::regex_constants::ECMAScript;
1020
+ if (buffer2.find('i') != string_type::npos)
1021
+ {
1022
+ options |= std::regex_constants::icase;
1023
+ }
1024
+ std::basic_regex<char_type> pattern(buffer, options);
1025
+ push_token(resources, resources.get_regex_operator(std::move(pattern)), ec);
1026
+ if (ec) {return path_expression_type();}
1027
+ buffer.clear();
1028
+ buffer2.clear();
1029
+ state_stack_.pop_back();
1030
+ break;
1031
+ }
1032
+ case path_state::regex_pattern:
1033
+ {
1034
+ switch (*p_)
1035
+ {
1036
+ case '/':
1037
+ {
1038
+ state_stack_.pop_back();
1039
+ ++p_;
1040
+ ++column_;
1041
+ }
1042
+ break;
1043
+
1044
+ default:
1045
+ buffer.push_back(*p_);
1046
+ ++p_;
1047
+ ++column_;
1048
+ break;
1049
+ }
1050
+ break;
1051
+ }
1052
+ case path_state::regex_options:
1053
+ {
1054
+ if (*p_ == 'i')
1055
+ {
1056
+ buffer2.push_back(*p_);
1057
+ ++p_;
1058
+ ++column_;
1059
+ }
1060
+ else
1061
+ {
1062
+ state_stack_.pop_back();
1063
+ }
1064
+ break;
1065
+ }
1066
+ case path_state::cmp_lt_or_lte:
1067
+ {
1068
+ switch(*p_)
1069
+ {
1070
+ case '=':
1071
+ push_token(resources, token_type(resources.get_lte_operator()), ec);
1072
+ if (ec) {return path_expression_type();}
1073
+ state_stack_.pop_back();
1074
+ ++p_;
1075
+ ++column_;
1076
+ break;
1077
+ default:
1078
+ push_token(resources, token_type(resources.get_lt_operator()), ec);
1079
+ if (ec) {return path_expression_type();}
1080
+ state_stack_.pop_back();
1081
+ break;
1082
+ }
1083
+ break;
1084
+ }
1085
+ case path_state::cmp_gt_or_gte:
1086
+ {
1087
+ switch(*p_)
1088
+ {
1089
+ case '=':
1090
+ push_token(resources, token_type(resources.get_gte_operator()), ec);
1091
+ if (ec) {return path_expression_type();}
1092
+ state_stack_.pop_back();
1093
+ ++p_;
1094
+ ++column_;
1095
+ break;
1096
+ default:
1097
+ //std::cout << "Parse: gt_operator\n";
1098
+ push_token(resources, token_type(resources.get_gt_operator()), ec);
1099
+ if (ec) {return path_expression_type();}
1100
+ state_stack_.pop_back();
1101
+ break;
1102
+ }
1103
+ break;
1104
+ }
1105
+ case path_state::cmp_ne:
1106
+ {
1107
+ switch(*p_)
1108
+ {
1109
+ case '=':
1110
+ push_token(resources, token_type(resources.get_ne_operator()), ec);
1111
+ if (ec) {return path_expression_type();}
1112
+ state_stack_.pop_back();
1113
+ ++p_;
1114
+ ++column_;
1115
+ break;
1116
+ default:
1117
+ ec = jsonpath_errc::expected_comparator;
1118
+ return path_expression_type();
1119
+ }
1120
+ break;
1121
+ }
1122
+ case path_state::identifier:
1123
+ push_token(resources, token_type(resources.new_selector(identifier_selector<Json,JsonReference>(buffer))), ec);
1124
+ if (ec) {return path_expression_type();}
1125
+ buffer.clear();
1126
+ state_stack_.pop_back();
1127
+ break;
1128
+ case path_state::single_quoted_string:
1129
+ switch (*p_)
1130
+ {
1131
+ case '\'':
1132
+ state_stack_.pop_back();
1133
+ ++p_;
1134
+ ++column_;
1135
+ break;
1136
+ case '\\':
1137
+ state_stack_.emplace_back(path_state::quoted_string_escape_char);
1138
+ ++p_;
1139
+ ++column_;
1140
+ break;
1141
+ default:
1142
+ buffer.push_back(*p_);
1143
+ ++p_;
1144
+ ++column_;
1145
+ break;
1146
+ };
1147
+ break;
1148
+ case path_state::double_quoted_string:
1149
+ switch (*p_)
1150
+ {
1151
+ case '\"':
1152
+ state_stack_.pop_back();
1153
+ ++p_;
1154
+ ++column_;
1155
+ break;
1156
+ case '\\':
1157
+ state_stack_.emplace_back(path_state::quoted_string_escape_char);
1158
+ ++p_;
1159
+ ++column_;
1160
+ break;
1161
+ default:
1162
+ buffer.push_back(*p_);
1163
+ ++p_;
1164
+ ++column_;
1165
+ break;
1166
+ };
1167
+ break;
1168
+ case path_state::comma_or_rbracket:
1169
+ switch (*p_)
1170
+ {
1171
+ case ' ':case '\t':case '\r':case '\n':
1172
+ advance_past_space_character();
1173
+ break;
1174
+ case ',':
1175
+ state_stack_.back() = path_state::bracket_specifier_or_union;
1176
+ ++p_;
1177
+ ++column_;
1178
+ break;
1179
+ case ']':
1180
+ state_stack_.pop_back();
1181
+ ++p_;
1182
+ ++column_;
1183
+ break;
1184
+ default:
1185
+ ec = jsonpath_errc::expected_comma_or_rbracket;
1186
+ return path_expression_type();
1187
+ }
1188
+ break;
1189
+ case path_state::expect_rbracket:
1190
+ switch (*p_)
1191
+ {
1192
+ case ' ':case '\t':case '\r':case '\n':
1193
+ advance_past_space_character();
1194
+ break;
1195
+ case ']':
1196
+ state_stack_.pop_back();
1197
+ ++p_;
1198
+ ++column_;
1199
+ break;
1200
+ default:
1201
+ ec = jsonpath_errc::expected_rbracket;
1202
+ return path_expression_type();
1203
+ }
1204
+ break;
1205
+ case path_state::expect_rparen:
1206
+ switch (*p_)
1207
+ {
1208
+ case ' ':case '\t':case '\r':case '\n':
1209
+ advance_past_space_character();
1210
+ break;
1211
+ case ')':
1212
+ ++p_;
1213
+ ++column_;
1214
+ push_token(resources, rparen_arg, ec);
1215
+ if (ec) {return path_expression_type();}
1216
+ state_stack_.back() = path_state::expression_rhs;
1217
+ break;
1218
+ default:
1219
+ ec = jsonpath_errc::expected_rparen;
1220
+ return path_expression_type();
1221
+ }
1222
+ break;
1223
+ case path_state::bracket_specifier_or_union:
1224
+ switch (*p_)
1225
+ {
1226
+ case ' ':case '\t':case '\r':case '\n':
1227
+ advance_past_space_character();
1228
+ break;
1229
+ case '(':
1230
+ {
1231
+ push_token(resources, token_type(begin_union_arg), ec);
1232
+ push_token(resources, token_type(begin_expression_arg), ec);
1233
+ push_token(resources, lparen_arg, ec);
1234
+ if (ec) {return path_expression_type();}
1235
+ state_stack_.back() = path_state::union_expression; // union
1236
+ state_stack_.emplace_back(path_state::expression);
1237
+ state_stack_.emplace_back(path_state::expect_rparen);
1238
+ state_stack_.emplace_back(path_state::expression_rhs);
1239
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
1240
+ ++p_;
1241
+ ++column_;
1242
+ break;
1243
+ }
1244
+ case '?':
1245
+ {
1246
+ push_token(resources, token_type(begin_union_arg), ec);
1247
+ push_token(resources, token_type(begin_filter_arg), ec);
1248
+ if (ec) {return path_expression_type();}
1249
+ state_stack_.back() = path_state::union_expression; // union
1250
+ state_stack_.emplace_back(path_state::filter_expression);
1251
+ state_stack_.emplace_back(path_state::expression_rhs);
1252
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
1253
+ ++p_;
1254
+ ++column_;
1255
+ break;
1256
+ }
1257
+ case '*':
1258
+ state_stack_.back() = path_state::wildcard_or_union;
1259
+ ++p_;
1260
+ ++column_;
1261
+ break;
1262
+ case '\'':
1263
+ state_stack_.back() = path_state::identifier_or_union;
1264
+ state_stack_.push_back(path_state::single_quoted_string);
1265
+ ++p_;
1266
+ ++column_;
1267
+ break;
1268
+ case '\"':
1269
+ state_stack_.back() = path_state::identifier_or_union;
1270
+ state_stack_.push_back(path_state::double_quoted_string);
1271
+ ++p_;
1272
+ ++column_;
1273
+ break;
1274
+ case ':': // slice_expression
1275
+ state_stack_.back() = path_state::index_or_slice_or_union;
1276
+ break;
1277
+ case '-':case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
1278
+ state_stack_.back() = path_state::index_or_slice_or_union;
1279
+ state_stack_.emplace_back(path_state::integer);
1280
+ break;
1281
+ case '$':
1282
+ push_token(resources, token_type(begin_union_arg), ec);
1283
+ push_token(resources, root_node_arg, ec);
1284
+ if (ec) {return path_expression_type();}
1285
+ state_stack_.back() = path_state::union_expression; // union
1286
+ state_stack_.emplace_back(path_state::relative_location);
1287
+ ++p_;
1288
+ ++column_;
1289
+ break;
1290
+ case '@':
1291
+ push_token(resources, token_type(begin_union_arg), ec);
1292
+ push_token(resources, token_type(current_node_arg), ec); // ISSUE
1293
+ push_token(resources, token_type(resources.new_selector(current_node_selector<Json,JsonReference>())), ec);
1294
+ if (ec) {return path_expression_type();}
1295
+ state_stack_.back() = path_state::union_expression; // union
1296
+ state_stack_.emplace_back(path_state::relative_location);
1297
+ ++p_;
1298
+ ++column_;
1299
+ break;
1300
+ default:
1301
+ ec = jsonpath_errc::expected_bracket_specifier_or_union;
1302
+ return path_expression_type();
1303
+ }
1304
+ break;
1305
+ case path_state::union_element:
1306
+ switch (*p_)
1307
+ {
1308
+ case ' ':case '\t':case '\r':case '\n':
1309
+ advance_past_space_character();
1310
+ break;
1311
+ case ':': // slice_expression
1312
+ state_stack_.back() = path_state::index_or_slice;
1313
+ break;
1314
+ case '-':case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
1315
+ state_stack_.back() = path_state::index_or_slice;
1316
+ state_stack_.emplace_back(path_state::integer);
1317
+ break;
1318
+ case '(':
1319
+ {
1320
+ push_token(resources, token_type(begin_expression_arg), ec);
1321
+ push_token(resources, lparen_arg, ec);
1322
+ if (ec) {return path_expression_type();}
1323
+ state_stack_.back() = path_state::expression;
1324
+ state_stack_.emplace_back(path_state::expect_rparen);
1325
+ state_stack_.emplace_back(path_state::expression_rhs);
1326
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
1327
+ ++p_;
1328
+ ++column_;
1329
+ break;
1330
+ }
1331
+ case '?':
1332
+ {
1333
+ push_token(resources, token_type(begin_filter_arg), ec);
1334
+ if (ec) {return path_expression_type();}
1335
+ state_stack_.back() = path_state::filter_expression;
1336
+ state_stack_.emplace_back(path_state::expression_rhs);
1337
+ state_stack_.emplace_back(path_state::path_or_literal_or_function);
1338
+ ++p_;
1339
+ ++column_;
1340
+ break;
1341
+ }
1342
+ case '*':
1343
+ push_token(resources, token_type(resources.new_selector(wildcard_selector<Json,JsonReference>())), ec);
1344
+ if (ec) {return path_expression_type();}
1345
+ state_stack_.back() = path_state::relative_location;
1346
+ ++p_;
1347
+ ++column_;
1348
+ break;
1349
+ case '$':
1350
+ push_token(resources, token_type(root_node_arg), ec);
1351
+ push_token(resources, token_type(resources.new_selector(root_selector<Json,JsonReference>(selector_id++))), ec);
1352
+ if (ec) {return path_expression_type();}
1353
+ state_stack_.back() = path_state::relative_location;
1354
+ ++p_;
1355
+ ++column_;
1356
+ break;
1357
+ case '@':
1358
+ push_token(resources, token_type(current_node_arg), ec); // ISSUE
1359
+ push_token(resources, token_type(resources.new_selector(current_node_selector<Json,JsonReference>())), ec);
1360
+ if (ec) {return path_expression_type();}
1361
+ state_stack_.back() = path_state::relative_location;
1362
+ ++p_;
1363
+ ++column_;
1364
+ break;
1365
+ case '\'':
1366
+ state_stack_.back() = path_state::identifier;
1367
+ state_stack_.push_back(path_state::single_quoted_string);
1368
+ ++p_;
1369
+ ++column_;
1370
+ break;
1371
+ case '\"':
1372
+ state_stack_.back() = path_state::identifier;
1373
+ state_stack_.push_back(path_state::double_quoted_string);
1374
+ ++p_;
1375
+ ++column_;
1376
+ break;
1377
+ default:
1378
+ ec = jsonpath_errc::expected_bracket_specifier_or_union;
1379
+ return path_expression_type();
1380
+ }
1381
+ break;
1382
+
1383
+ case path_state::integer:
1384
+ switch(*p_)
1385
+ {
1386
+ case '-':
1387
+ buffer.push_back(*p_);
1388
+ state_stack_.back() = path_state::digit;
1389
+ ++p_;
1390
+ ++column_;
1391
+ break;
1392
+ default:
1393
+ state_stack_.back() = path_state::digit;
1394
+ break;
1395
+ }
1396
+ break;
1397
+ case path_state::digit:
1398
+ switch(*p_)
1399
+ {
1400
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
1401
+ buffer.push_back(*p_);
1402
+ ++p_;
1403
+ ++column_;
1404
+ break;
1405
+ default:
1406
+ state_stack_.pop_back(); // digit
1407
+ break;
1408
+ }
1409
+ break;
1410
+ case path_state::index_or_slice_or_union:
1411
+ switch(*p_)
1412
+ {
1413
+ case ' ':case '\t':case '\r':case '\n':
1414
+ advance_past_space_character();
1415
+ break;
1416
+ case ']':
1417
+ {
1418
+ if (buffer.empty())
1419
+ {
1420
+ ec = jsonpath_errc::invalid_number;
1421
+ return path_expression_type();
1422
+ }
1423
+ int64_t n{0};
1424
+ auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n);
1425
+ if (!r)
1426
+ {
1427
+ ec = jsonpath_errc::invalid_number;
1428
+ return path_expression_type();
1429
+ }
1430
+ push_token(resources, token_type(resources.new_selector(index_selector<Json,JsonReference>(n))), ec);
1431
+ if (ec) {return path_expression_type();}
1432
+ buffer.clear();
1433
+ state_stack_.pop_back(); // index_or_slice_or_union
1434
+ ++p_;
1435
+ ++column_;
1436
+ break;
1437
+ }
1438
+ case ',':
1439
+ {
1440
+ push_token(resources, token_type(begin_union_arg), ec);
1441
+ if (ec) {return path_expression_type();}
1442
+ if (buffer.empty())
1443
+ {
1444
+ ec = jsonpath_errc::invalid_number;
1445
+ return path_expression_type();
1446
+ }
1447
+ else
1448
+ {
1449
+ int64_t n{0};
1450
+ auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n);
1451
+ if (!r)
1452
+ {
1453
+ ec = jsonpath_errc::invalid_number;
1454
+ return path_expression_type();
1455
+ }
1456
+ push_token(resources, token_type(resources.new_selector(index_selector<Json,JsonReference>(n))), ec);
1457
+ if (ec) {return path_expression_type();}
1458
+
1459
+ buffer.clear();
1460
+ }
1461
+ push_token(resources, token_type(separator_arg), ec);
1462
+ if (ec) {return path_expression_type();}
1463
+ buffer.clear();
1464
+ state_stack_.back() = path_state::union_expression; // union
1465
+ state_stack_.emplace_back(path_state::union_element);
1466
+ ++p_;
1467
+ ++column_;
1468
+ break;
1469
+ }
1470
+ case ':':
1471
+ {
1472
+ if (!buffer.empty())
1473
+ {
1474
+ int64_t n{0};
1475
+ auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n);
1476
+ if (!r)
1477
+ {
1478
+ ec = jsonpath_errc::invalid_number;
1479
+ return path_expression_type();
1480
+ }
1481
+ slic.start_ = n;
1482
+ buffer.clear();
1483
+ }
1484
+ push_token(resources, token_type(begin_union_arg), ec);
1485
+ if (ec) {return path_expression_type();}
1486
+ state_stack_.back() = path_state::union_expression; // union
1487
+ state_stack_.emplace_back(path_state::slice_expression_stop);
1488
+ state_stack_.emplace_back(path_state::integer);
1489
+ ++p_;
1490
+ ++column_;
1491
+ break;
1492
+ }
1493
+ default:
1494
+ ec = jsonpath_errc::expected_rbracket;
1495
+ return path_expression_type();
1496
+ }
1497
+ break;
1498
+ case path_state::slice_expression_stop:
1499
+ {
1500
+ if (!buffer.empty())
1501
+ {
1502
+ int64_t n{0};
1503
+ auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n);
1504
+ if (!r)
1505
+ {
1506
+ ec = jsonpath_errc::invalid_number;
1507
+ return path_expression_type();
1508
+ }
1509
+ slic.stop_ = jsoncons::optional<int64_t>(n);
1510
+ buffer.clear();
1511
+ }
1512
+ switch(*p_)
1513
+ {
1514
+ case ' ':case '\t':case '\r':case '\n':
1515
+ advance_past_space_character();
1516
+ break;
1517
+ case ']':
1518
+ case ',':
1519
+ push_token(resources, token_type(resources.new_selector(slice_selector<Json,JsonReference>(slic))), ec);
1520
+ if (ec) {return path_expression_type();}
1521
+ slic = slice{};
1522
+ state_stack_.pop_back(); // bracket_specifier2
1523
+ break;
1524
+ case ':':
1525
+ state_stack_.back() = path_state::slice_expression_step;
1526
+ state_stack_.emplace_back(path_state::integer);
1527
+ ++p_;
1528
+ ++column_;
1529
+ break;
1530
+ default:
1531
+ ec = jsonpath_errc::expected_rbracket;
1532
+ return path_expression_type();
1533
+ }
1534
+ break;
1535
+ }
1536
+ case path_state::slice_expression_step:
1537
+ {
1538
+ if (!buffer.empty())
1539
+ {
1540
+ int64_t n{0};
1541
+ auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n);
1542
+ if (!r)
1543
+ {
1544
+ ec = jsonpath_errc::invalid_number;
1545
+ return path_expression_type();
1546
+ }
1547
+ if (n == 0)
1548
+ {
1549
+ ec = jsonpath_errc::step_cannot_be_zero;
1550
+ return path_expression_type();
1551
+ }
1552
+ slic.step_ = n;
1553
+ buffer.clear();
1554
+ }
1555
+ switch(*p_)
1556
+ {
1557
+ case ' ':case '\t':case '\r':case '\n':
1558
+ advance_past_space_character();
1559
+ break;
1560
+ case ']':
1561
+ case ',':
1562
+ push_token(resources, token_type(resources.new_selector(slice_selector<Json,JsonReference>(slic))), ec);
1563
+ if (ec) {return path_expression_type();}
1564
+ buffer.clear();
1565
+ slic = slice{};
1566
+ state_stack_.pop_back(); // slice_expression_step
1567
+ break;
1568
+ default:
1569
+ ec = jsonpath_errc::expected_rbracket;
1570
+ return path_expression_type();
1571
+ }
1572
+ break;
1573
+ }
1574
+
1575
+ case path_state::bracketed_unquoted_name_or_union:
1576
+ switch (*p_)
1577
+ {
1578
+ case ' ':case '\t':case '\r':case '\n':
1579
+ advance_past_space_character();
1580
+ break;
1581
+ case ']':
1582
+ push_token(resources, token_type(resources.new_selector(identifier_selector<Json,JsonReference>(buffer))), ec);
1583
+ if (ec) {return path_expression_type();}
1584
+ buffer.clear();
1585
+ state_stack_.pop_back();
1586
+ ++p_;
1587
+ ++column_;
1588
+ break;
1589
+ case '.':
1590
+ push_token(resources, token_type(begin_union_arg), ec);
1591
+ push_token(resources, token_type(resources.new_selector(identifier_selector<Json,JsonReference>(buffer))), ec);
1592
+ if (ec) {return path_expression_type();}
1593
+ buffer.clear();
1594
+ state_stack_.back() = path_state::union_expression; // union
1595
+ state_stack_.emplace_back(path_state::relative_path);
1596
+ ++p_;
1597
+ ++column_;
1598
+ break;
1599
+ case '[':
1600
+ push_token(resources, token_type(begin_union_arg), ec);
1601
+ push_token(resources, token_type(resources.new_selector(identifier_selector<Json,JsonReference>(buffer))), ec);
1602
+ if (ec) {return path_expression_type();}
1603
+ state_stack_.back() = path_state::union_expression; // union
1604
+ state_stack_.emplace_back(path_state::relative_path);
1605
+ ++p_;
1606
+ ++column_;
1607
+ break;
1608
+ case ',':
1609
+ push_token(resources, token_type(begin_union_arg), ec);
1610
+ push_token(resources, token_type(resources.new_selector(identifier_selector<Json,JsonReference>(buffer))), ec);
1611
+ push_token(resources, token_type(separator_arg), ec);
1612
+ if (ec) {return path_expression_type();}
1613
+ buffer.clear();
1614
+ state_stack_.back() = path_state::union_expression; // union
1615
+ state_stack_.emplace_back(path_state::relative_path);
1616
+ ++p_;
1617
+ ++column_;
1618
+ break;
1619
+ default:
1620
+ buffer.push_back(*p_);
1621
+ ++p_;
1622
+ ++column_;
1623
+ break;
1624
+ }
1625
+ break;
1626
+ case path_state::union_expression:
1627
+ switch (*p_)
1628
+ {
1629
+ case ' ':case '\t':case '\r':case '\n':
1630
+ advance_past_space_character();
1631
+ break;
1632
+ case '.':
1633
+ state_stack_.emplace_back(path_state::relative_path);
1634
+ ++p_;
1635
+ ++column_;
1636
+ break;
1637
+ case '[':
1638
+ state_stack_.emplace_back(path_state::bracket_specifier_or_union);
1639
+ ++p_;
1640
+ ++column_;
1641
+ break;
1642
+ case ',':
1643
+ push_token(resources, token_type(separator_arg), ec);
1644
+ if (ec) {return path_expression_type();}
1645
+ state_stack_.emplace_back(path_state::union_element);
1646
+ ++p_;
1647
+ ++column_;
1648
+ break;
1649
+ case ']':
1650
+ push_token(resources, token_type(end_union_arg), ec);
1651
+ if (ec) {return path_expression_type();}
1652
+ state_stack_.pop_back();
1653
+ ++p_;
1654
+ ++column_;
1655
+ break;
1656
+ default:
1657
+ ec = jsonpath_errc::expected_rbracket;
1658
+ return path_expression_type();
1659
+ }
1660
+ break;
1661
+ case path_state::identifier_or_union:
1662
+ switch (*p_)
1663
+ {
1664
+ case ' ':case '\t':case '\r':case '\n':
1665
+ advance_past_space_character();
1666
+ break;
1667
+ case ']':
1668
+ push_token(resources, token_type(resources.new_selector(identifier_selector<Json,JsonReference>(buffer))), ec);
1669
+ if (ec) {return path_expression_type();}
1670
+ buffer.clear();
1671
+ state_stack_.pop_back();
1672
+ ++p_;
1673
+ ++column_;
1674
+ break;
1675
+ case ',':
1676
+ push_token(resources, token_type(begin_union_arg), ec);
1677
+ push_token(resources, token_type(resources.new_selector(identifier_selector<Json,JsonReference>(buffer))), ec);
1678
+ push_token(resources, token_type(separator_arg), ec);
1679
+ if (ec) {return path_expression_type();}
1680
+ buffer.clear();
1681
+ state_stack_.back() = path_state::union_expression; // union
1682
+ state_stack_.emplace_back(path_state::union_element);
1683
+ ++p_;
1684
+ ++column_;
1685
+ break;
1686
+ default:
1687
+ ec = jsonpath_errc::expected_rbracket;
1688
+ return path_expression_type();
1689
+ }
1690
+ break;
1691
+ case path_state::bracketed_wildcard:
1692
+ switch (*p_)
1693
+ {
1694
+ case ' ':case '\t':case '\r':case '\n':
1695
+ advance_past_space_character();
1696
+ break;
1697
+ case '[':
1698
+ case ']':
1699
+ case ',':
1700
+ case '.':
1701
+ push_token(resources, token_type(resources.new_selector(wildcard_selector<Json,JsonReference>())), ec);
1702
+ if (ec) {return path_expression_type();}
1703
+ buffer.clear();
1704
+ state_stack_.pop_back();
1705
+ break;
1706
+ default:
1707
+ ec = jsonpath_errc::expected_rbracket;
1708
+ return path_expression_type();
1709
+ }
1710
+ break;
1711
+ case path_state::index_or_slice:
1712
+ switch(*p_)
1713
+ {
1714
+ case ' ':case '\t':case '\r':case '\n':
1715
+ advance_past_space_character();
1716
+ break;
1717
+ case ',':
1718
+ case ']':
1719
+ {
1720
+ if (buffer.empty())
1721
+ {
1722
+ ec = jsonpath_errc::invalid_number;
1723
+ return path_expression_type();
1724
+ }
1725
+ else
1726
+ {
1727
+ int64_t n{0};
1728
+ auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n);
1729
+ if (!r)
1730
+ {
1731
+ ec = jsonpath_errc::invalid_number;
1732
+ return path_expression_type();
1733
+ }
1734
+ push_token(resources, token_type(resources.new_selector(index_selector<Json,JsonReference>(n))), ec);
1735
+ if (ec) {return path_expression_type();}
1736
+
1737
+ buffer.clear();
1738
+ }
1739
+ state_stack_.pop_back(); // bracket_specifier
1740
+ break;
1741
+ }
1742
+ case ':':
1743
+ {
1744
+ if (!buffer.empty())
1745
+ {
1746
+ int64_t n{0};
1747
+ auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n);
1748
+ if (!r)
1749
+ {
1750
+ ec = jsonpath_errc::invalid_number;
1751
+ return path_expression_type();
1752
+ }
1753
+ slic.start_ = n;
1754
+ buffer.clear();
1755
+ }
1756
+ state_stack_.back() = path_state::slice_expression_stop;
1757
+ state_stack_.emplace_back(path_state::integer);
1758
+ ++p_;
1759
+ ++column_;
1760
+ break;
1761
+ }
1762
+ default:
1763
+ ec = jsonpath_errc::expected_rbracket;
1764
+ return path_expression_type();
1765
+ }
1766
+ break;
1767
+ case path_state::wildcard_or_union:
1768
+ switch (*p_)
1769
+ {
1770
+ case ' ':case '\t':case '\r':case '\n':
1771
+ advance_past_space_character();
1772
+ break;
1773
+ case ']':
1774
+ push_token(resources, token_type(resources.new_selector(wildcard_selector<Json,JsonReference>())), ec);
1775
+ if (ec) {return path_expression_type();}
1776
+ buffer.clear();
1777
+ state_stack_.pop_back();
1778
+ ++p_;
1779
+ ++column_;
1780
+ break;
1781
+ case ',':
1782
+ push_token(resources, token_type(begin_union_arg), ec);
1783
+ push_token(resources, token_type(resources.new_selector(wildcard_selector<Json,JsonReference>())), ec);
1784
+ push_token(resources, token_type(separator_arg), ec);
1785
+ if (ec) {return path_expression_type();}
1786
+ buffer.clear();
1787
+ state_stack_.back() = path_state::union_expression; // union
1788
+ state_stack_.emplace_back(path_state::union_element);
1789
+ ++p_;
1790
+ ++column_;
1791
+ break;
1792
+ default:
1793
+ ec = jsonpath_errc::expected_rbracket;
1794
+ return path_expression_type();
1795
+ }
1796
+ break;
1797
+ case path_state::quoted_string_escape_char:
1798
+ switch (*p_)
1799
+ {
1800
+ case '\"':
1801
+ buffer.push_back('\"');
1802
+ ++p_;
1803
+ ++column_;
1804
+ state_stack_.pop_back();
1805
+ break;
1806
+ case '\'':
1807
+ buffer.push_back('\'');
1808
+ ++p_;
1809
+ ++column_;
1810
+ state_stack_.pop_back();
1811
+ break;
1812
+ case '\\':
1813
+ buffer.push_back('\\');
1814
+ ++p_;
1815
+ ++column_;
1816
+ state_stack_.pop_back();
1817
+ break;
1818
+ case '/':
1819
+ buffer.push_back('/');
1820
+ ++p_;
1821
+ ++column_;
1822
+ state_stack_.pop_back();
1823
+ break;
1824
+ case 'b':
1825
+ buffer.push_back('\b');
1826
+ ++p_;
1827
+ ++column_;
1828
+ state_stack_.pop_back();
1829
+ break;
1830
+ case 'f':
1831
+ buffer.push_back('\f');
1832
+ ++p_;
1833
+ ++column_;
1834
+ state_stack_.pop_back();
1835
+ break;
1836
+ case 'n':
1837
+ buffer.push_back('\n');
1838
+ ++p_;
1839
+ ++column_;
1840
+ state_stack_.pop_back();
1841
+ break;
1842
+ case 'r':
1843
+ buffer.push_back('\r');
1844
+ ++p_;
1845
+ ++column_;
1846
+ state_stack_.pop_back();
1847
+ break;
1848
+ case 't':
1849
+ buffer.push_back('\t');
1850
+ ++p_;
1851
+ ++column_;
1852
+ state_stack_.pop_back();
1853
+ break;
1854
+ case 'u':
1855
+ ++p_;
1856
+ ++column_;
1857
+ state_stack_.back() = path_state::escape_u1;
1858
+ break;
1859
+ default:
1860
+ ec = jsonpath_errc::illegal_escaped_character;
1861
+ return path_expression_type();
1862
+ }
1863
+ break;
1864
+ case path_state::escape_u1:
1865
+ cp = append_to_codepoint(0, *p_, ec);
1866
+ if (ec)
1867
+ {
1868
+ return path_expression_type();
1869
+ }
1870
+ ++p_;
1871
+ ++column_;
1872
+ state_stack_.back() = path_state::escape_u2;
1873
+ break;
1874
+ case path_state::escape_u2:
1875
+ cp = append_to_codepoint(cp, *p_, ec);
1876
+ if (ec)
1877
+ {
1878
+ return path_expression_type();
1879
+ }
1880
+ ++p_;
1881
+ ++column_;
1882
+ state_stack_.back() = path_state::escape_u3;
1883
+ break;
1884
+ case path_state::escape_u3:
1885
+ cp = append_to_codepoint(cp, *p_, ec);
1886
+ if (ec)
1887
+ {
1888
+ return path_expression_type();
1889
+ }
1890
+ ++p_;
1891
+ ++column_;
1892
+ state_stack_.back() = path_state::escape_u4;
1893
+ break;
1894
+ case path_state::escape_u4:
1895
+ cp = append_to_codepoint(cp, *p_, ec);
1896
+ if (ec)
1897
+ {
1898
+ return path_expression_type();
1899
+ }
1900
+ if (unicode_traits::is_high_surrogate(cp))
1901
+ {
1902
+ ++p_;
1903
+ ++column_;
1904
+ state_stack_.back() = path_state::escape_expect_surrogate_pair1;
1905
+ }
1906
+ else
1907
+ {
1908
+ unicode_traits::convert(&cp, 1, buffer);
1909
+ ++p_;
1910
+ ++column_;
1911
+ state_stack_.pop_back();
1912
+ }
1913
+ break;
1914
+ case path_state::escape_expect_surrogate_pair1:
1915
+ switch (*p_)
1916
+ {
1917
+ case '\\':
1918
+ ++p_;
1919
+ ++column_;
1920
+ state_stack_.back() = path_state::escape_expect_surrogate_pair2;
1921
+ break;
1922
+ default:
1923
+ ec = jsonpath_errc::invalid_codepoint;
1924
+ return path_expression_type();
1925
+ }
1926
+ break;
1927
+ case path_state::escape_expect_surrogate_pair2:
1928
+ switch (*p_)
1929
+ {
1930
+ case 'u':
1931
+ ++p_;
1932
+ ++column_;
1933
+ state_stack_.back() = path_state::escape_u5;
1934
+ break;
1935
+ default:
1936
+ ec = jsonpath_errc::invalid_codepoint;
1937
+ return path_expression_type();
1938
+ }
1939
+ break;
1940
+ case path_state::escape_u5:
1941
+ cp2 = append_to_codepoint(0, *p_, ec);
1942
+ if (ec)
1943
+ {
1944
+ return path_expression_type();
1945
+ }
1946
+ ++p_;
1947
+ ++column_;
1948
+ state_stack_.back() = path_state::escape_u6;
1949
+ break;
1950
+ case path_state::escape_u6:
1951
+ cp2 = append_to_codepoint(cp2, *p_, ec);
1952
+ if (ec)
1953
+ {
1954
+ return path_expression_type();
1955
+ }
1956
+ ++p_;
1957
+ ++column_;
1958
+ state_stack_.back() = path_state::escape_u7;
1959
+ break;
1960
+ case path_state::escape_u7:
1961
+ cp2 = append_to_codepoint(cp2, *p_, ec);
1962
+ if (ec)
1963
+ {
1964
+ return path_expression_type();
1965
+ }
1966
+ ++p_;
1967
+ ++column_;
1968
+ state_stack_.back() = path_state::escape_u8;
1969
+ break;
1970
+ case path_state::escape_u8:
1971
+ {
1972
+ cp2 = append_to_codepoint(cp2, *p_, ec);
1973
+ if (ec)
1974
+ {
1975
+ return path_expression_type();
1976
+ }
1977
+ uint32_t codepoint = 0x10000 + ((cp & 0x3FF) << 10) + (cp2 & 0x3FF);
1978
+ unicode_traits::convert(&codepoint, 1, buffer);
1979
+ state_stack_.pop_back();
1980
+ ++p_;
1981
+ ++column_;
1982
+ break;
1983
+ }
1984
+ case path_state::filter_expression:
1985
+ {
1986
+ switch(*p_)
1987
+ {
1988
+ case ' ':case '\t':case '\r':case '\n':
1989
+ advance_past_space_character();
1990
+ break;
1991
+ case ',':
1992
+ case ']':
1993
+ {
1994
+ push_token(resources, token_type(end_filter_arg), ec);
1995
+ if (ec) {return path_expression_type();}
1996
+ state_stack_.pop_back();
1997
+ break;
1998
+ }
1999
+ default:
2000
+ ec = jsonpath_errc::expected_comma_or_rbracket;
2001
+ return path_expression_type();
2002
+ }
2003
+ break;
2004
+ }
2005
+ case path_state::expression:
2006
+ {
2007
+ switch(*p_)
2008
+ {
2009
+ case ' ':case '\t':case '\r':case '\n':
2010
+ advance_past_space_character();
2011
+ break;
2012
+ case ',':
2013
+ case ']':
2014
+ {
2015
+ push_token(resources, token_type(end_index_expression_arg), ec);
2016
+ if (ec) {return path_expression_type();}
2017
+ state_stack_.pop_back();
2018
+ break;
2019
+ }
2020
+ default:
2021
+ ec = jsonpath_errc::expected_comma_or_rbracket;
2022
+ return path_expression_type();
2023
+ }
2024
+ break;
2025
+ }
2026
+ default:
2027
+ ++p_;
2028
+ ++column_;
2029
+ break;
2030
+ }
2031
+ }
2032
+
2033
+ if (state_stack_.empty())
2034
+ {
2035
+ ec = jsonpath_errc::syntax_error;
2036
+ return path_expression_type();
2037
+ }
2038
+
2039
+ while (state_stack_.size() > 1)
2040
+ {
2041
+ switch (state_stack_.back())
2042
+ {
2043
+ case path_state::name_or_lbracket:
2044
+ state_stack_.back() = path_state::relative_path;
2045
+ break;
2046
+ case path_state::relative_path:
2047
+ state_stack_.back() = path_state::identifier_or_function_expr;
2048
+ state_stack_.emplace_back(path_state::unquoted_string);
2049
+ break;
2050
+ case path_state::identifier_or_function_expr:
2051
+ if (!buffer.empty()) // Can't be quoted string
2052
+ {
2053
+ push_token(resources, token_type(resources.new_selector(identifier_selector<Json,JsonReference>(buffer))), ec);
2054
+ if (ec) {return path_expression_type();}
2055
+ }
2056
+ state_stack_.pop_back();
2057
+ break;
2058
+ case path_state::unquoted_string:
2059
+ state_stack_.pop_back(); // unquoted_string
2060
+ break;
2061
+ case path_state::relative_location:
2062
+ state_stack_.pop_back();
2063
+ break;
2064
+ case path_state::identifier:
2065
+ if (!buffer.empty()) // Can't be quoted string
2066
+ {
2067
+ push_token(resources, token_type(resources.new_selector(identifier_selector<Json,JsonReference>(buffer))), ec);
2068
+ if (ec) {return path_expression_type();}
2069
+ }
2070
+ state_stack_.pop_back();
2071
+ break;
2072
+ case path_state::parent_operator:
2073
+ {
2074
+ push_token(resources, token_type(resources.new_selector(parent_node_selector<Json,JsonReference>(ancestor_depth))), ec);
2075
+ if (ec) { return path_expression_type(); }
2076
+ paths_required = true;
2077
+ state_stack_.pop_back();
2078
+ break;
2079
+ }
2080
+ case path_state::ancestor_depth:
2081
+ state_stack_.pop_back();
2082
+ break;
2083
+ default:
2084
+ ec = jsonpath_errc::syntax_error;
2085
+ return path_expression_type();
2086
+ }
2087
+ }
2088
+
2089
+ if (state_stack_.size() > 2)
2090
+ {
2091
+ ec = jsonpath_errc::unexpected_eof;
2092
+ return path_expression_type();
2093
+ }
2094
+
2095
+ //std::cout << "\nTokens\n\n";
2096
+ //for (const auto& tok : output_stack_)
2097
+ //{
2098
+ // std::cout << tok.to_string() << "\n";
2099
+ //}
2100
+ //std::cout << "\n";
2101
+
2102
+ if (output_stack_.empty() || !operator_stack_.empty())
2103
+ {
2104
+ ec = jsonpath_errc::unexpected_eof;
2105
+ return path_expression_type();
2106
+ }
2107
+
2108
+ return path_expression_type(output_stack_.back().selector_, paths_required);
2109
+ }
2110
+
2111
+ void advance_past_space_character()
2112
+ {
2113
+ switch (*p_)
2114
+ {
2115
+ case ' ':case '\t':
2116
+ ++p_;
2117
+ ++column_;
2118
+ break;
2119
+ case '\r':
2120
+ if (p_+1 < end_input_ && *(p_+1) == '\n')
2121
+ ++p_;
2122
+ ++line_;
2123
+ column_ = 1;
2124
+ ++p_;
2125
+ break;
2126
+ case '\n':
2127
+ ++line_;
2128
+ column_ = 1;
2129
+ ++p_;
2130
+ break;
2131
+ default:
2132
+ break;
2133
+ }
2134
+ }
2135
+
2136
+ void unwind_rparen(std::error_code& ec)
2137
+ {
2138
+ auto it = operator_stack_.rbegin();
2139
+ while (it != operator_stack_.rend() && !it->is_lparen())
2140
+ {
2141
+ output_stack_.emplace_back(std::move(*it));
2142
+ ++it;
2143
+ }
2144
+ if (it == operator_stack_.rend())
2145
+ {
2146
+ ec = jsonpath_errc::unbalanced_parentheses;
2147
+ return;
2148
+ }
2149
+ ++it;
2150
+ operator_stack_.erase(it.base(),operator_stack_.end());
2151
+ }
2152
+
2153
+ void push_token(jsoncons::jsonpath::detail::static_resources<value_type,reference>& resources, token_type&& tok, std::error_code& ec)
2154
+ {
2155
+ //std::cout << tok.to_string() << "\n";
2156
+ switch (tok.token_kind())
2157
+ {
2158
+ case jsonpath_token_kind::begin_filter:
2159
+ output_stack_.emplace_back(std::move(tok));
2160
+ operator_stack_.emplace_back(token_type(lparen_arg));
2161
+ break;
2162
+ case jsonpath_token_kind::end_filter:
2163
+ {
2164
+ //std::cout << "push_token end_filter 1\n";
2165
+ //for (const auto& tok2 : output_stack_)
2166
+ //{
2167
+ // std::cout << tok2.to_string() << "\n";
2168
+ //}
2169
+ //std::cout << "\n\n";
2170
+ unwind_rparen(ec);
2171
+ if (ec)
2172
+ {
2173
+ return;
2174
+ }
2175
+ std::vector<token_type> toks;
2176
+ auto it = output_stack_.rbegin();
2177
+ while (it != output_stack_.rend() && it->token_kind() != jsonpath_token_kind::begin_filter)
2178
+ {
2179
+ toks.emplace_back(std::move(*it));
2180
+ ++it;
2181
+ }
2182
+ if (it == output_stack_.rend())
2183
+ {
2184
+ ec = jsonpath_errc::unbalanced_parentheses;
2185
+ return;
2186
+ }
2187
+ std::reverse(toks.begin(), toks.end());
2188
+ ++it;
2189
+ output_stack_.erase(it.base(),output_stack_.end());
2190
+
2191
+ if (!output_stack_.empty() && output_stack_.back().is_path())
2192
+ {
2193
+ output_stack_.back().selector_->append_selector(resources.new_selector(filter_selector<Json,JsonReference>(expression_type(std::move(toks)))));
2194
+ }
2195
+ else
2196
+ {
2197
+ output_stack_.emplace_back(token_type(resources.new_selector(filter_selector<Json,JsonReference>(expression_type(std::move(toks))))));
2198
+ }
2199
+ //std::cout << "push_token end_filter 2\n";
2200
+ //for (const auto& tok2 : output_stack_)
2201
+ //{
2202
+ // std::cout << tok2.to_string() << "\n";
2203
+ //}
2204
+ //std::cout << "\n\n";
2205
+ break;
2206
+ }
2207
+ case jsonpath_token_kind::begin_expression:
2208
+ //std::cout << "begin_expression\n";
2209
+ output_stack_.emplace_back(std::move(tok));
2210
+ operator_stack_.emplace_back(token_type(lparen_arg));
2211
+ break;
2212
+ case jsonpath_token_kind::end_index_expression:
2213
+ {
2214
+ //std::cout << "jsonpath_token_kind::end_index_expression\n";
2215
+ //for (const auto& t : output_stack_)
2216
+ //{
2217
+ // std::cout << t.to_string() << "\n";
2218
+ //}
2219
+ //std::cout << "/jsonpath_token_kind::end_index_expression\n";
2220
+ unwind_rparen(ec);
2221
+ if (ec)
2222
+ {
2223
+ return;
2224
+ }
2225
+ std::vector<token_type> toks;
2226
+ auto it = output_stack_.rbegin();
2227
+ while (it != output_stack_.rend() && it->token_kind() != jsonpath_token_kind::begin_expression)
2228
+ {
2229
+ toks.emplace_back(std::move(*it));
2230
+ ++it;
2231
+ }
2232
+ if (it == output_stack_.rend())
2233
+ {
2234
+ ec = jsonpath_errc::unbalanced_parentheses;
2235
+ return;
2236
+ }
2237
+ std::reverse(toks.begin(), toks.end());
2238
+ ++it;
2239
+ output_stack_.erase(it.base(),output_stack_.end());
2240
+
2241
+ if (!output_stack_.empty() && output_stack_.back().is_path())
2242
+ {
2243
+ output_stack_.back().selector_->append_selector(resources.new_selector(index_expression_selector<Json,JsonReference>(expression_type(std::move(toks)))));
2244
+ }
2245
+ else
2246
+ {
2247
+ output_stack_.emplace_back(token_type(resources.new_selector(index_expression_selector<Json,JsonReference>(expression_type(std::move(toks))))));
2248
+ }
2249
+ break;
2250
+ }
2251
+ case jsonpath_token_kind::end_argument_expression:
2252
+ {
2253
+ //std::cout << "jsonpath_token_kind::end_index_expression\n";
2254
+ //for (const auto& t : output_stack_)
2255
+ //{
2256
+ // std::cout << t.to_string() << "\n";
2257
+ //}
2258
+ //std::cout << "/jsonpath_token_kind::end_index_expression\n";
2259
+ unwind_rparen(ec);
2260
+ if (ec)
2261
+ {
2262
+ return;
2263
+ }
2264
+ std::vector<token_type> toks;
2265
+ auto it = output_stack_.rbegin();
2266
+ while (it != output_stack_.rend() && it->token_kind() != jsonpath_token_kind::begin_expression)
2267
+ {
2268
+ toks.emplace_back(std::move(*it));
2269
+ ++it;
2270
+ }
2271
+ if (it == output_stack_.rend())
2272
+ {
2273
+ ec = jsonpath_errc::unbalanced_parentheses;
2274
+ return;
2275
+ }
2276
+ std::reverse(toks.begin(), toks.end());
2277
+ ++it;
2278
+ output_stack_.erase(it.base(),output_stack_.end());
2279
+ output_stack_.emplace_back(token_type(jsoncons::make_unique<expression_type>(std::move(toks))));
2280
+ break;
2281
+ }
2282
+ case jsonpath_token_kind::selector:
2283
+ {
2284
+ if (!output_stack_.empty() && output_stack_.back().is_path())
2285
+ {
2286
+ output_stack_.back().selector_->append_selector(std::move(tok.selector_));
2287
+ }
2288
+ else
2289
+ {
2290
+ output_stack_.emplace_back(std::move(tok));
2291
+ }
2292
+ break;
2293
+ }
2294
+ case jsonpath_token_kind::separator:
2295
+ output_stack_.emplace_back(std::move(tok));
2296
+ break;
2297
+ case jsonpath_token_kind::begin_union:
2298
+ output_stack_.emplace_back(std::move(tok));
2299
+ break;
2300
+ case jsonpath_token_kind::end_union:
2301
+ {
2302
+ std::vector<selector_type*> expressions;
2303
+ auto it = output_stack_.rbegin();
2304
+ while (it != output_stack_.rend() && it->token_kind() != jsonpath_token_kind::begin_union)
2305
+ {
2306
+ if (it->token_kind() == jsonpath_token_kind::selector)
2307
+ {
2308
+ expressions.emplace_back(std::move(it->selector_));
2309
+ }
2310
+ do
2311
+ {
2312
+ ++it;
2313
+ }
2314
+ while (it != output_stack_.rend() && it->token_kind() != jsonpath_token_kind::begin_union && it->token_kind() != jsonpath_token_kind::separator);
2315
+ if (it->token_kind() == jsonpath_token_kind::separator)
2316
+ {
2317
+ ++it;
2318
+ }
2319
+ }
2320
+ if (it == output_stack_.rend())
2321
+ {
2322
+ ec = jsonpath_errc::unbalanced_parentheses;
2323
+ return;
2324
+ }
2325
+ std::reverse(expressions.begin(), expressions.end());
2326
+ ++it;
2327
+ output_stack_.erase(it.base(),output_stack_.end());
2328
+
2329
+ if (!output_stack_.empty() && output_stack_.back().is_path())
2330
+ {
2331
+ output_stack_.back().selector_->append_selector(resources.new_selector(union_selector<Json,JsonReference>(std::move(expressions))));
2332
+ }
2333
+ else
2334
+ {
2335
+ output_stack_.emplace_back(token_type(resources.new_selector(union_selector<Json,JsonReference>(std::move(expressions)))));
2336
+ }
2337
+ break;
2338
+ }
2339
+ case jsonpath_token_kind::lparen:
2340
+ operator_stack_.emplace_back(std::move(tok));
2341
+ break;
2342
+ case jsonpath_token_kind::rparen:
2343
+ {
2344
+ unwind_rparen(ec);
2345
+ break;
2346
+ }
2347
+ case jsonpath_token_kind::end_function:
2348
+ {
2349
+ //std::cout << "jsonpath_token_kind::end_function\n";
2350
+ unwind_rparen(ec);
2351
+ if (ec)
2352
+ {
2353
+ return;
2354
+ }
2355
+ std::vector<token_type> toks;
2356
+ auto it = output_stack_.rbegin();
2357
+ std::size_t arg_count = 0;
2358
+ while (it != output_stack_.rend() && it->token_kind() != jsonpath_token_kind::function)
2359
+ {
2360
+ if (it->token_kind() == jsonpath_token_kind::argument)
2361
+ {
2362
+ ++arg_count;
2363
+ }
2364
+ toks.emplace_back(std::move(*it));
2365
+ ++it;
2366
+ }
2367
+ if (it == output_stack_.rend())
2368
+ {
2369
+ ec = jsonpath_errc::unbalanced_parentheses;
2370
+ return;
2371
+ }
2372
+ std::reverse(toks.begin(), toks.end());
2373
+ if (it->arity() && arg_count != *(it->arity()))
2374
+ {
2375
+ ec = jsonpath_errc::invalid_arity;
2376
+ return;
2377
+ }
2378
+ toks.push_back(std::move(*it));
2379
+ ++it;
2380
+ output_stack_.erase(it.base(),output_stack_.end());
2381
+
2382
+ if (!output_stack_.empty() && output_stack_.back().is_path())
2383
+ {
2384
+ output_stack_.back().selector_->append_selector(resources.new_selector(function_selector<Json,JsonReference>(expression_type(std::move(toks)))));
2385
+ }
2386
+ else
2387
+ {
2388
+ output_stack_.emplace_back(token_type(resources.new_selector(function_selector<Json,JsonReference>(std::move(toks)))));
2389
+ }
2390
+ break;
2391
+ }
2392
+ case jsonpath_token_kind::literal:
2393
+ if (!output_stack_.empty() && (output_stack_.back().token_kind() == jsonpath_token_kind::current_node || output_stack_.back().token_kind() == jsonpath_token_kind::root_node))
2394
+ {
2395
+ output_stack_.back() = std::move(tok);
2396
+ }
2397
+ else
2398
+ {
2399
+ output_stack_.emplace_back(std::move(tok));
2400
+ }
2401
+ break;
2402
+ case jsonpath_token_kind::function:
2403
+ output_stack_.emplace_back(std::move(tok));
2404
+ operator_stack_.emplace_back(token_type(lparen_arg));
2405
+ break;
2406
+ case jsonpath_token_kind::argument:
2407
+ output_stack_.emplace_back(std::move(tok));
2408
+ break;
2409
+ case jsonpath_token_kind::root_node:
2410
+ case jsonpath_token_kind::current_node:
2411
+ output_stack_.emplace_back(std::move(tok));
2412
+ break;
2413
+ case jsonpath_token_kind::unary_operator:
2414
+ case jsonpath_token_kind::binary_operator:
2415
+ {
2416
+ if (operator_stack_.empty() || operator_stack_.back().is_lparen())
2417
+ {
2418
+ operator_stack_.emplace_back(std::move(tok));
2419
+ }
2420
+ else if (tok.precedence_level() < operator_stack_.back().precedence_level()
2421
+ || (tok.precedence_level() == operator_stack_.back().precedence_level() && tok.is_right_associative()))
2422
+ {
2423
+ operator_stack_.emplace_back(std::move(tok));
2424
+ }
2425
+ else
2426
+ {
2427
+ auto it = operator_stack_.rbegin();
2428
+ while (it != operator_stack_.rend() && it->is_operator()
2429
+ && (tok.precedence_level() > it->precedence_level()
2430
+ || (tok.precedence_level() == it->precedence_level() && tok.is_right_associative())))
2431
+ {
2432
+ output_stack_.emplace_back(std::move(*it));
2433
+ ++it;
2434
+ }
2435
+
2436
+ operator_stack_.erase(it.base(),operator_stack_.end());
2437
+ operator_stack_.emplace_back(std::move(tok));
2438
+ }
2439
+ break;
2440
+ }
2441
+ default:
2442
+ break;
2443
+ }
2444
+ //std::cout << " " << "Output Stack\n";
2445
+ //for (auto&& t : output_stack_)
2446
+ //{
2447
+ // std::cout << t.to_string(2) << "\n";
2448
+ //}
2449
+ //if (!operator_stack_.empty())
2450
+ //{
2451
+ // std::cout << " " << "Operator Stack\n";
2452
+ // for (auto&& t : operator_stack_)
2453
+ // {
2454
+ // std::cout << t.to_string(2) << "\n";
2455
+ // }
2456
+ //}
2457
+ }
2458
+
2459
+ uint32_t append_to_codepoint(uint32_t cp, int c, std::error_code& ec)
2460
+ {
2461
+ cp *= 16;
2462
+ if (c >= '0' && c <= '9')
2463
+ {
2464
+ cp += c - '0';
2465
+ }
2466
+ else if (c >= 'a' && c <= 'f')
2467
+ {
2468
+ cp += c - 'a' + 10;
2469
+ }
2470
+ else if (c >= 'A' && c <= 'F')
2471
+ {
2472
+ cp += c - 'A' + 10;
2473
+ }
2474
+ else
2475
+ {
2476
+ ec = jsonpath_errc::invalid_codepoint;
2477
+ }
2478
+ return cp;
2479
+ }
2480
+ };
2481
+
2482
+ } // namespace detail
2483
+
2484
+ template <class Json,class JsonReference = const Json&>
2485
+ class jsonpath_expression
2486
+ {
2487
+ public:
2488
+ using evaluator_t = typename jsoncons::jsonpath::detail::jsonpath_evaluator<Json, JsonReference>;
2489
+ using char_type = typename evaluator_t::char_type;
2490
+ using string_type = typename evaluator_t::string_type;
2491
+ using string_view_type = typename evaluator_t::string_view_type;
2492
+ using value_type = typename evaluator_t::value_type;
2493
+ using reference = typename evaluator_t::reference;
2494
+ using parameter_type = parameter<Json>;
2495
+ using json_selector_t = typename evaluator_t::path_expression_type;
2496
+ using path_value_pair_type = typename evaluator_t::path_value_pair_type;
2497
+ using json_location_type = typename evaluator_t::json_location_type;
2498
+ using function_type = std::function<value_type(jsoncons::span<const parameter_type>, std::error_code& ec)>;
2499
+ private:
2500
+ jsoncons::jsonpath::detail::static_resources<value_type,reference> static_resources_;
2501
+ json_selector_t expr_;
2502
+ public:
2503
+ jsonpath_expression(jsoncons::jsonpath::detail::static_resources<value_type,reference>&& resources,
2504
+ json_selector_t&& expr)
2505
+ : static_resources_(std::move(resources)),
2506
+ expr_(std::move(expr))
2507
+ {
2508
+ }
2509
+
2510
+ jsonpath_expression(jsoncons::jsonpath::detail::static_resources<value_type,reference>&& resources,
2511
+ json_selector_t&& expr, std::vector<function_type>&& custom_functions)
2512
+ : static_resources_(std::move(resources)),
2513
+ expr_(std::move(expr), std::move(custom_functions))
2514
+ {
2515
+ }
2516
+
2517
+ template <class BinaryCallback>
2518
+ typename std::enable_if<traits_extension::is_binary_function_object<BinaryCallback,const string_type&,reference>::value,void>::type
2519
+ evaluate(reference instance, BinaryCallback callback, result_options options = result_options()) const
2520
+ {
2521
+ jsoncons::jsonpath::detail::dynamic_resources<Json,reference> resources;
2522
+ auto f = [&callback](const json_location_type& path, reference val)
2523
+ {
2524
+ callback(path.to_string(), val);
2525
+ };
2526
+ expr_.evaluate(resources, instance, resources.root_path_node(), instance, f, options);
2527
+ }
2528
+
2529
+ Json evaluate(reference instance, result_options options = result_options()) const
2530
+ {
2531
+ if ((options & result_options::path) == result_options::path)
2532
+ {
2533
+ jsoncons::jsonpath::detail::dynamic_resources<Json,reference> resources;
2534
+
2535
+ Json result(json_array_arg);
2536
+ auto callback = [&result](const json_location_type& p, reference)
2537
+ {
2538
+ result.emplace_back(p.to_string());
2539
+ };
2540
+ expr_.evaluate(resources, instance, resources.root_path_node(), instance, callback, options);
2541
+ return result;
2542
+ }
2543
+ else
2544
+ {
2545
+ jsoncons::jsonpath::detail::dynamic_resources<Json,reference> resources;
2546
+ return expr_.evaluate(resources, instance, resources.current_path_node(), instance, options);
2547
+ }
2548
+ }
2549
+
2550
+ static jsonpath_expression compile(const string_view_type& path)
2551
+ {
2552
+ jsoncons::jsonpath::detail::static_resources<value_type,reference> resources;
2553
+
2554
+ evaluator_t e;
2555
+ json_selector_t expr = e.compile(resources, path);
2556
+ return jsonpath_expression(std::move(resources), std::move(expr));
2557
+ }
2558
+
2559
+ static jsonpath_expression compile(const string_view_type& path, std::error_code& ec)
2560
+ {
2561
+ jsoncons::jsonpath::detail::static_resources<value_type,reference> resources;
2562
+ evaluator_t e;
2563
+ json_selector_t expr = e.compile(resources, path, ec);
2564
+ return jsonpath_expression(std::move(resources), std::move(expr));
2565
+ }
2566
+
2567
+ static jsonpath_expression compile(const string_view_type& path,
2568
+ const custom_functions<Json>& functions)
2569
+ {
2570
+ jsoncons::jsonpath::detail::static_resources<value_type,reference> resources(functions);
2571
+
2572
+ evaluator_t e;
2573
+ json_selector_t expr = e.compile(resources, path);
2574
+ return jsonpath_expression(std::move(resources), std::move(expr));
2575
+ }
2576
+
2577
+ static jsonpath_expression compile(const string_view_type& path,
2578
+ const custom_functions<Json>& functions,
2579
+ std::error_code& ec)
2580
+ {
2581
+ jsoncons::jsonpath::detail::static_resources<value_type,reference> resources(functions);
2582
+ evaluator_t e;
2583
+ json_selector_t expr = e.compile(resources, path, ec);
2584
+ return jsonpath_expression(std::move(resources), std::move(expr));
2585
+ }
2586
+ };
2587
+
2588
+ template <class Json>
2589
+ jsonpath_expression<Json> make_expression(const typename Json::string_view_type& expr,
2590
+ const custom_functions<Json>& functions = custom_functions<Json>())
2591
+ {
2592
+ return jsonpath_expression<Json>::compile(expr, functions);
2593
+ }
2594
+
2595
+ template <class Json>
2596
+ jsonpath_expression<Json> make_expression(const typename Json::string_view_type& expr, std::error_code& ec)
2597
+ {
2598
+ return jsonpath_expression<Json>::compile(expr, ec);
2599
+ }
2600
+
2601
+ template <class Json>
2602
+ jsonpath_expression<Json> make_expression(const typename Json::string_view_type& expr,
2603
+ const custom_functions<Json>& functions,
2604
+ std::error_code& ec)
2605
+ {
2606
+ return jsonpath_expression<Json>::compile(expr, functions, ec);
2607
+ }
2608
+
2609
+ } // namespace jsonpath
2610
+ } // namespace jsoncons
2611
+
2612
+ #endif