jsoncons 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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