1 /** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef PANDA_VERIF_PARSER_H_ 17 #define PANDA_VERIF_PARSER_H_ 18 19 #include "charset.h" 20 #include "util/callable.h" 21 22 namespace panda::parser { 23 24 template <typename...> 25 struct type_sum; 26 27 template <typename...> 28 struct type_prod; 29 30 struct op_next; 31 struct op_end; 32 struct op_optional; 33 struct op_action; 34 struct op_sequence; 35 struct op_or; 36 struct op_and; 37 struct op_lookup; 38 struct op_not; 39 struct op_times; 40 struct op_times_ref; 41 42 template <typename A, typename B, typename C> 43 struct if_type { 44 }; 45 46 template <typename A, typename C> 47 struct if_type<A, A, C> { 48 using type = C; 49 }; 50 51 template <typename T> 52 T &ref_to(); 53 54 template <typename T> 55 T val_of(); 56 57 enum class action { START, PARSED, CANCEL }; 58 59 template <typename Context, typename Type, typename Char, typename Iter> 60 struct base_parser : public verifier::callable<bool(Context &, Iter &, Iter)> { 61 template <typename F> 62 constexpr base_parser(const F &f) : verifier::callable<bool(Context &, Iter &, Iter)> {f} 63 { 64 } 65 66 using Ctx = Context; 67 using T = Type; 68 69 base_parser() = default; 70 71 template <typename NType> 72 using next = base_parser<Context, type_sum<NType, T>, Char, Iter>; 73 74 using p = base_parser<Context, type_sum<op_next, T>, Char, Iter>; 75 76 static next<charset<Char>> of_charset(const charset<Char> &c) 77 { 78 static const auto l = [c](Context &, Iter &start, Iter end) { 79 Iter s = start; 80 while (s != end && c(*s)) { 81 s++; 82 } 83 bool result = (s != start); 84 if (result) { 85 start = s; 86 } 87 return result; 88 }; 89 return l; 90 } 91 92 static next<Char *> of_string(Char *str) 93 { 94 static const auto l = [=](Context &, Iter &start, Iter end) { 95 Iter s = start; 96 Iter c = str; 97 while (s != end && *c != 0 && *c == *s) { 98 ++c; 99 ++s; 100 } 101 bool result = (*c == 0); 102 if (result) { 103 start = s; 104 } 105 return result; 106 }; 107 return l; 108 } 109 110 static next<op_end> end() 111 { 112 static const auto l = [](Context &, Iter &start, Iter end) { return start == end; }; 113 return l; 114 } 115 116 next<op_optional> operator~() && 117 { 118 static const auto l = [p = *this](Context &c, Iter &start, Iter end) { 119 p(c, start, end); 120 return true; 121 }; 122 return l; 123 } 124 125 next<op_optional> operator~() const & 126 { 127 static const auto l = [this](Context &c, Iter &start, Iter end) { 128 (*this)(c, start, end); 129 return true; 130 }; 131 return l; 132 } 133 134 template <typename F> 135 auto operator|=(F f) const -> 136 typename if_type<decltype(f(action::START, ref_to<Context>(), ref_to<Iter>(), val_of<Iter>(), val_of<Iter>())), 137 bool, next<type_prod<op_action, F>>>::type 138 { 139 static const auto l = [p = *this, f](Context &c, Iter &start, Iter end) { 140 auto saved = start; 141 if (!f(action::START, c, start, start, end)) { 142 start = saved; 143 return false; 144 } 145 bool result = p(c, start, end); 146 auto new_saved = saved; 147 if (!result) { 148 f(action::CANCEL, c, new_saved, start, end); 149 start = saved; 150 return false; 151 } 152 if (!f(action::PARSED, c, new_saved, start, end)) { 153 start = saved; 154 return false; 155 } 156 return true; 157 }; 158 return l; 159 } 160 161 template <typename F> 162 auto operator|=(F f) const -> 163 typename if_type<decltype(f(action::START, ref_to<Context>(), ref_to<Iter>(), val_of<Iter>())), bool, 164 next<type_prod<op_action, F>>>::type 165 { 166 static const auto l = [p = *this, f](Context &c, Iter &start, Iter end) { 167 auto saved = start; 168 if (!f(action::START, c, start, start)) { 169 start = saved; 170 return false; 171 } 172 bool result = p(c, start, end); 173 auto new_saved = saved; 174 if (!result) { 175 f(action::CANCEL, c, new_saved, start); 176 start = saved; 177 return false; 178 } 179 if (!f(action::PARSED, c, new_saved, start)) { 180 start = saved; 181 return false; 182 } 183 return true; 184 }; 185 return l; 186 } 187 188 template <typename F> 189 auto operator|=(F f) const -> typename if_type<decltype(f(action::START, ref_to<Context>(), ref_to<Iter>())), bool, 190 next<type_prod<op_action, F>>>::type 191 { 192 static const auto l = [p = *this, f](Context &c, Iter &start, Iter end) { 193 auto saved = start; 194 if (!f(action::START, c, start)) { 195 start = saved; 196 return false; 197 } 198 bool result = p(c, start, end); 199 auto new_saved = saved; 200 if (!result) { 201 f(action::CANCEL, c, new_saved); 202 start = saved; 203 return false; 204 } 205 if (!f(action::PARSED, c, new_saved)) { 206 start = saved; 207 return false; 208 } 209 return true; 210 }; 211 return l; 212 } 213 214 template <typename F> 215 auto operator|=(F f) const -> 216 typename if_type<decltype(f(action::START, ref_to<Context>())), bool, next<type_prod<op_action, F>>>::type 217 { 218 static const auto l = [p = *this, f](Context &c, Iter &start, Iter end) { 219 auto saved = start; 220 if (!f(action::START, c)) { 221 start = saved; 222 return false; 223 } 224 bool result = p(c, start, end); 225 if (!result) { 226 f(action::CANCEL, c); 227 start = saved; 228 return false; 229 } 230 if (!f(action::PARSED, c)) { 231 start = saved; 232 return false; 233 } 234 return true; 235 }; 236 return l; 237 } 238 239 template <typename P> 240 next<type_prod<op_sequence, typename P::T>> operator>>(P pa) const 241 { 242 static const auto l = [left = *this, right = pa](Context &c, Iter &start, Iter end) { 243 auto saved = start; 244 if (left(c, start, end) && right(c, start, end)) { 245 return true; 246 } 247 start = saved; 248 return false; 249 }; 250 return l; 251 } 252 253 template <typename P> 254 next<type_prod<op_or, typename P::T>> operator|(P pa) const 255 { 256 static const auto l = [left = *this, right = pa](Context &c, Iter &start, Iter end) { 257 auto saved = start; 258 if (left(c, start, end)) { 259 return true; 260 } 261 start = saved; 262 if (right(c, start, end)) { 263 return true; 264 } 265 start = saved; 266 return false; 267 }; 268 return l; 269 } 270 271 template <typename P> 272 next<type_prod<op_and, typename P::T>> operator&(P pa) const 273 { 274 static const auto l = [left = *this, right = pa](Context &c, Iter &start, Iter end) { 275 auto saved = start; 276 if (left(c, start, end)) { 277 start = saved; 278 return right(c, start, end); 279 } 280 start = saved; 281 return false; 282 }; 283 return l; 284 } 285 286 template <typename P> 287 next<type_prod<op_lookup, typename P::T>> operator<<(P pa) const 288 { 289 static const auto l = [left = *this, right = pa](Context &c, Iter &start, Iter end) { 290 auto saved1 = start; 291 if (left(c, start, end)) { 292 auto saved2 = start; 293 if (right(c, start, end)) { 294 start = saved2; 295 return true; 296 } 297 } 298 start = saved1; 299 return false; 300 }; 301 return l; 302 } 303 304 next<op_not> operator!() && 305 { 306 static const auto l = [p = *this](Context &c, Iter &start, Iter end) { 307 auto saved = start; 308 if (p(c, start, end)) { 309 start = saved; 310 return false; 311 } 312 start = saved; 313 return true; 314 }; 315 return l; 316 } 317 318 next<op_not> operator!() const & 319 { 320 static const auto l = [this](Context &c, Iter &start, Iter end) { 321 auto saved = start; 322 if ((*this)(c, start, end)) { 323 start = saved; 324 return false; 325 } 326 start = saved; 327 return true; 328 }; 329 return l; 330 } 331 332 next<op_times> operator*() && 333 { 334 static const auto l = [p = *this](Context &c, Iter &start, Iter end) { 335 while (true) { 336 auto saved = start; 337 if (!p(c, start, end)) { 338 start = saved; 339 break; 340 } 341 } 342 return true; 343 }; 344 return l; 345 } 346 347 next<op_times_ref> operator*() const & 348 { 349 static const auto l = [this](Context &c, Iter &start, Iter end) { 350 while (true) { 351 auto saved = start; 352 if (!(*this)(c, start, end)) { 353 start = saved; 354 break; 355 } 356 } 357 return true; 358 }; 359 return l; 360 } 361 }; 362 363 struct initial; 364 365 template <typename Context, typename Char, typename Iter> 366 using parser = base_parser<Context, initial, Char, Iter>; 367 368 } // namespace panda::parser 369 370 #endif //! PANDA_VERIF_PARSER_H_ 371