JODA  0.13.1 (59b41972)
JSON On-Demand Analysis
Choose_Actions.h
Go to the documentation of this file.
1 //
2 // Created by Nico on 08/05/2019.
3 //
4 
5 #ifndef JODA_CHOOSE_ACTIONS_H
6 #define JODA_CHOOSE_ACTIONS_H
7 
8 #include "../grammar/Grammar.h"
9 #include "../states/States.h"
10 
15 
17 
18 template <>
20  template <typename Input>
21  static void apply(const Input &in, chooseState &state) {
22  if (state.valProv.first == nullptr) {
23  std::string pointer = in.string();
24  state.valProv.first = std::make_unique<joda::query::PointerProvider>(
25  pointer.substr(1, pointer.size() - 2));
26  return;
27  }
28  if (state.valProv.second == nullptr) {
29  std::string pointer = in.string();
30  state.valProv.second = std::make_unique<joda::query::PointerProvider>(
31  pointer.substr(1, pointer.size() - 2));
32  return;
33  }
34  assert(false);
35  }
36 };
37 template <>
39  static inline std::string unescape(const std::string &s) {
40  std::string res;
41  std::string::const_iterator it = s.begin();
42  while (it != s.end()) {
43  char c = *it++;
44  if (c == '\\' && it != s.end()) {
45  switch (*it++) {
46  case '\\':
47  c = '\\';
48  break;
49  case '"':
50  c = '"';
51  break;
52  // all other escapes
53  default:
54  // invalid escape sequence - skip it. alternatively you can copy it
55  // as is, throw an exception...
56  continue;
57  }
58  }
59  res += c;
60  }
61 
62  return res;
63  }
64  template <typename Input>
65  static void apply(const Input &in, chooseState &state) {
66  std::string str = in.string();
67  // Unescape string
68  auto unescaped = unescape(str.substr(1, str.size() - 2));
69 
70  if (state.valProv.first == nullptr) {
71  state.valProv.first =
72  std::make_unique<joda::query::StringProvider>(unescaped);
73  return;
74  }
75  if (state.valProv.second == nullptr) {
76  state.valProv.second =
77  std::make_unique<joda::query::StringProvider>(unescaped);
78  return;
79  }
80  assert(false);
81  }
82 };
83 template <>
85  template <typename Input>
86  static void apply(const Input &in, chooseState &state) {
87  std::string str = in.string();
88  bool b = str == "true";
89  if (!b) { // Not "true"
90  b = str == "false";
91  if (!b)
92  assert(false); // Also not false => Error
93  else
94  b = false; // Is "False" so b = false
95  }
96 
97  if (state.valProv.first == nullptr) {
98  state.valProv.first = std::make_unique<joda::query::BoolProvider>(b);
99  return;
100  }
101  if (state.valProv.second == nullptr) {
102  state.valProv.second = std::make_unique<joda::query::BoolProvider>(b);
103  return;
104  }
105  assert(false);
106  }
107 };
108 template <>
110  template <typename Input>
111  static bool apply(const Input &in, chooseState &state) {
112  std::string str = in.string();
113 
114  std::unique_ptr<joda::query::IValueProvider> ival;
115 
116  bool try_unisgned = false;
117  bool try_double = false;
118 
119  try {
120  int64_t i = std::stol(str);
121  ival = std::make_unique<joda::query::Int64Provider>(i);
122  } catch (std::out_of_range &e) {
123  try_unisgned = true;
124  } catch (std::exception &e) {
125  try_double = true;
126  }
127 
128  if (try_unisgned) {
129  try {
130  u_int64_t i = std::stoul(str);
131  ival = std::make_unique<joda::query::UInt64Provider>(i);
132  } catch (std::exception &e) {
133  try_double = true;
134  }
135  }
136 
137  try {
138  double i = std::stod(str);
139  ival = std::make_unique<joda::query::DoubleProvider>(i);
140  } catch (std::exception &e) {
141  return false;
142  }
143 
144  DCHECK(ival != nullptr);
145 
146  if (state.valProv.first == nullptr) {
147  state.valProv.first = std::move(ival);
148  return true;
149  }
150  if (state.valProv.second == nullptr) {
151  state.valProv.second = std::move(ival);
152  return true;
153  }
154  return false;
155  }
156 };
157 template <>
159  template <typename Input>
160  static void apply(const Input &in, chooseState &state) {
161  std::string str = in.string();
162 
163  if (str.size() == 1) {
164  state.comp = GT;
165  return;
166  }
167  if (str.size() == 2) {
168  state.comp = GTE;
169  return;
170  }
171  assert(false);
172  }
173 };
174 
175 template <>
177  template <typename Input>
178  static void apply(const Input &in, chooseState &state) {
179  std::string str = in.string();
180 
181  if (str.size() == 1) {
182  state.comp = LT;
183  return;
184  }
185  if (str.size() == 2) {
186  state.comp = LTE;
187  return;
188  }
189  assert(false);
190  }
191 };
192 
193 template <>
195  template <typename Input>
196  static void apply(const Input &in, chooseState &state) {
197  std::string str = in.string();
198 
199  assert(str.size() == 2);
200  if (str[0] == '!') {
201  state.comp = NEQU;
202  return;
203  }
204  if (str[0] == '=') {
205  state.comp = EQU;
206  return;
207  }
208  assert(false);
209  }
210 };
211 
212 template <>
214  template <typename Input>
215  static bool apply(const Input &in, chooseState &state) {
216  if (state.valProv.first == nullptr) {
217  assert(false && "There has to be at least one value");
218  return false; // May not happen that
219  }
220 
221  std::unique_ptr<joda::query::Predicate> pred = nullptr;
222  try {
223  if (state.valProv.second == nullptr) { // Only one value =>
224  // ValToPredicate
225  assert(state.comp == NONE && "If not 'NONE' something went wrong");
226  pred = std::make_unique<joda::query::ValToPredicate>(
227  std::move(state.valProv.first));
228  } else {
229  try {
230  switch (state.comp) {
231  case GT:
232  pred = std::make_unique<joda::query::ComparePredicate>(
233  std::move(state.valProv.first),
234  std::move(state.valProv.second), true, false);
235  break;
236  case GTE:
237  pred = std::make_unique<joda::query::ComparePredicate>(
238  std::move(state.valProv.first),
239  std::move(state.valProv.second), true, true);
240  break;
241  case LT:
242  pred = std::make_unique<joda::query::ComparePredicate>(
243  std::move(state.valProv.first),
244  std::move(state.valProv.second), false, false);
245  break;
246  case LTE:
247  pred = std::make_unique<joda::query::ComparePredicate>(
248  std::move(state.valProv.first),
249  std::move(state.valProv.second), false, true);
250  break;
251  case EQU:
252  pred = std::make_unique<joda::query::EqualizePredicate>(
253  std::move(state.valProv.first),
254  std::move(state.valProv.second), true);
255  break;
256  case NEQU:
257  pred = std::make_unique<joda::query::EqualizePredicate>(
258  std::move(state.valProv.first),
259  std::move(state.valProv.second), false);
260  break;
261  case NONE:
262  assert(false && "May not happen");
263  return false;
264  break;
265  }
266  state.comp = NONE;
267  state.valProv.first = nullptr;
268  state.valProv.second = nullptr;
269 
270  } catch (const joda::query::NotComparableException &e) {
271  throw tao::pegtl::parse_error("These values cannot be compared. ",
272  in);
273  } catch (const joda::query::NotEqualizableException &e) {
274  throw tao::pegtl::parse_error(
275  "These values cannot be compared for (un)equality.", in);
276  };
277  }
278  } catch (const joda::query::WrongParameterException &e) {
279  throw tao::pegtl::parse_error(e.what(), in);
280  }
281  assert(pred != nullptr);
282 
283  state.preds.top().second.push_back(std::move(pred));
284  return true;
285  }
286 };
287 
288 template <>
290  template <typename Input>
291  static void apply(const Input &in, chooseState &state) {
292  std::string str = in.string();
293 
294  auto it = std::find_if(str.begin(), str.end(),
295  std::not1(std::ptr_fun(::isspace)));
296  if (it != str.end()) {
297  if (*it == '!') { // SHould it be negated?
298  // Negate last Pred
299  assert(state.preds.top().second.back() != nullptr);
300  auto tmp = std::make_unique<joda::query::NegatePredicate>(
301  std::move(state.preds.top().second.back()));
302  state.preds.top().second.back() = std::move(tmp);
303  }
304  }
305  }
306 };
307 
308 template <>
310  template <typename Input>
311  static void apply(const Input &in, chooseState &state) {
312  assert(!state.preds.empty());
313  assert(state.preds.top().first == AND);
314  auto pair = std::move(state.preds.top());
315  state.preds.pop();
316  assert(!pair.second.empty());
317  std::unique_ptr<joda::query::Predicate> tmpPtr = nullptr;
318  if (pair.second.size() > 1) {
319  for (int i = pair.second.size() - 1; i >= 0; --i) {
320  if (tmpPtr == nullptr)
321  tmpPtr = std::move(pair.second[i]);
322  else {
323  auto andPtr = std::make_unique<joda::query::AndPredicate>(
324  std::move(pair.second[i]), std::move(tmpPtr));
325  tmpPtr = std::move(andPtr);
326  }
327  }
328  } else
329  tmpPtr = std::move(pair.second.front());
330  assert(!state.preds.empty());
331  state.preds.top().second.push_back(std::move(tmpPtr));
332  }
333 };
334 template <>
336  template <typename Input>
337  static void apply(const Input &in, chooseState &state) {
338  assert(!state.preds.empty());
339  assert(state.preds.top().first == OR);
340  auto pair = std::move(state.preds.top());
341  state.preds.pop();
342  assert(!pair.second.empty());
343  std::unique_ptr<joda::query::Predicate> tmpPtr = nullptr;
344  if (pair.second.size() > 1) {
345  for (int i = pair.second.size() - 1; i >= 0; --i) {
346  if (tmpPtr == nullptr)
347  tmpPtr = std::move(pair.second[i]);
348  else {
349  auto andPtr = std::make_unique<joda::query::OrPredicate>(
350  std::move(pair.second[i]), std::move(tmpPtr));
351  tmpPtr = std::move(andPtr);
352  }
353  }
354  } else
355  tmpPtr = std::move(pair.second.front());
356  assert(!state.preds.empty());
357  state.preds.top().second.push_back(std::move(tmpPtr));
358  }
359 };
360 
361 template <>
363  template <typename Input>
364  static void apply(const Input &in, chooseState &state) {}
365 };
366 template <>
368  template <typename Input>
369  static void apply(const Input &in, chooseState &state) {
370  state.preds.emplace(std::make_pair(
371  AND, std::vector<std::unique_ptr<joda::query::Predicate>>()));
372  }
373 };
374 template <>
376  template <typename Input>
377  static void apply(const Input &in, chooseState &state) {
378  state.preds.emplace(std::make_pair(
379  OR, std::vector<std::unique_ptr<joda::query::Predicate>>()));
380  }
381 };
382 template <>
384  template <typename Input>
385  static void apply(const Input &in, chooseState &state) {
386  state.preds.emplace(std::make_pair(
387  BASE, std::vector<std::unique_ptr<joda::query::Predicate>>()));
388  }
389 };
390 } // namespace joda::queryparsing::grammar
391 #endif // JODA_CHOOSE_ACTIONS_H
Definition: ComparePredicate.h:16
Definition: EqualizePredicate.h:16
Definition: IValueProvider.h:46
virtual const char * what() const
Definition: IValueProvider.h:49
@ LTE
Definition: Query_State.h:38
@ GTE
Definition: Query_State.h:38
@ NEQU
Definition: Query_State.h:38
@ GT
Definition: Query_State.h:38
@ NONE
Definition: Query_State.h:38
@ LT
Definition: Query_State.h:38
@ EQU
Definition: Query_State.h:38
@ BASE
Definition: Query_State.h:39
@ AND
Definition: Query_State.h:39
@ OR
Definition: Query_State.h:39
Definition: Literals.h:142
Definition: Literals.h:137
Definition: Literals.h:65
static void apply(const Input &in, chooseState &state)
Definition: Choose_Actions.h:311
static void apply(const Input &in, chooseState &state)
Definition: Choose_Actions.h:369
static void apply(const Input &in, chooseState &state)
Definition: Choose_Actions.h:86
static bool apply(const Input &in, chooseState &state)
Definition: Choose_Actions.h:215
static void apply(const Input &in, chooseState &state)
Definition: Choose_Actions.h:196
static void apply(const Input &in, chooseState &state)
Definition: Choose_Actions.h:385
static void apply(const Input &in, chooseState &state)
Definition: Choose_Actions.h:160
static void apply(const Input &in, chooseState &state)
Definition: Choose_Actions.h:178
static bool apply(const Input &in, chooseState &state)
Definition: Choose_Actions.h:111
static void apply(const Input &in, chooseState &state)
Definition: Choose_Actions.h:337
static void apply(const Input &in, chooseState &state)
Definition: Choose_Actions.h:377
static void apply(const Input &in, chooseState &state)
Definition: Choose_Actions.h:21
static void apply(const Input &in, chooseState &state)
Definition: Choose_Actions.h:364
static std::string unescape(const std::string &s)
Definition: Choose_Actions.h:39
static void apply(const Input &in, chooseState &state)
Definition: Choose_Actions.h:65
static void apply(const Input &in, chooseState &state)
Definition: Choose_Actions.h:291
Definition: Choose_State.h:13
Comparison comp
Definition: Choose_State.h:61
std::pair< std::unique_ptr< joda::query::IValueProvider >, std::unique_ptr< joda::query::IValueProvider > > valProv
Definition: Choose_State.h:60
predStack preds
Definition: Choose_State.h:57
Definition: Literals.h:122
Definition: Literals.h:90
Definition: Literals.h:150
Definition: Literals.h:85
Definition: Literals.h:87
Definition: Literals.h:148
Definition: Literals.h:145
Definition: Literals.h:27
Definition: Literals.h:151
Definition: Literals.h:135