1 /* 2 * Copyright (c) 2021 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_VERIFICATION_DEBUG_PARSER_PARSER_H_ 17 #define PANDA_VERIFICATION_DEBUG_PARSER_PARSER_H_ 18 19 #include "charset.h" 20 #include "verification/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 if (!result) { 147 f(action::CANCEL, c, saved, start, end); 148 start = saved; 149 return false; 150 } 151 if (!f(action::PARSED, c, saved, start, end)) { 152 start = saved; 153 return false; 154 } 155 return true; 156 }; 157 return l; 158 } 159 160 template <typename F> 161 auto operator|=(F f) const -> 162 typename if_type<decltype(f(action::START, ref_to<Context>(), ref_to<Iter>(), val_of<Iter>())), bool, 163 next<type_prod<op_action, F>>>::type 164 { 165 static const auto l = [p = *this, f](Context &c, Iter &start, Iter end) { 166 auto saved = start; 167 if (!f(action::START, c, start, start)) { 168 start = saved; 169 return false; 170 } 171 bool result = p(c, start, end); 172 if (!result) { 173 f(action::CANCEL, c, saved, start); 174 start = saved; 175 return false; 176 } 177 if (!f(action::PARSED, c, saved, start)) { 178 start = saved; 179 return false; 180 } 181 return true; 182 }; 183 return l; 184 } 185 186 template <typename F> 187 auto operator|=(F f) const -> typename if_type<decltype(f(action::START, ref_to<Context>(), ref_to<Iter>())), bool, 188 next<type_prod<op_action, F>>>::type 189 { 190 static const auto l = [p = *this, f](Context &c, Iter &start, Iter end) { 191 auto saved = start; 192 if (!f(action::START, c, start)) { 193 start = saved; 194 return false; 195 } 196 bool result = p(c, start, end); 197 if (!result) { 198 f(action::CANCEL, c, saved); 199 start = saved; 200 return false; 201 } 202 if (!f(action::PARSED, c, saved)) { 203 start = saved; 204 return false; 205 } 206 return true; 207 }; 208 return l; 209 } 210 211 template <typename F> 212 auto operator|=(F f) const -> 213 typename if_type<decltype(f(action::START, ref_to<Context>())), bool, next<type_prod<op_action, F>>>::type 214 { 215 static const auto l = [p = *this, f](Context &c, Iter &start, Iter end) { 216 auto saved = start; 217 if (!f(action::START, c)) { 218 start = saved; 219 return false; 220 } 221 bool result = p(c, start, end); 222 if (!result) { 223 f(action::CANCEL, c); 224 start = saved; 225 return false; 226 } 227 if (!f(action::PARSED, c)) { 228 start = saved; 229 return false; 230 } 231 return true; 232 }; 233 return l; 234 } 235 236 template <typename P> 237 next<type_prod<op_sequence, typename P::T>> operator>>(P param_p) const 238 { 239 static const auto l = [left = *this, right = param_p](Context &c, Iter &start, Iter end) { 240 auto saved = start; 241 if (left(c, start, end) && right(c, start, end)) { 242 return true; 243 } 244 start = saved; 245 return false; 246 }; 247 return l; 248 } 249 250 template <typename P> 251 next<type_prod<op_or, typename P::T>> operator|(P param_p) const 252 { 253 static const auto l = [left = *this, right = param_p](Context &c, Iter &start, Iter end) { 254 auto saved = start; 255 if (left(c, start, end)) { 256 return true; 257 } 258 start = saved; 259 if (right(c, start, end)) { 260 return true; 261 } 262 start = saved; 263 return false; 264 }; 265 return l; 266 } 267 268 template <typename P> 269 next<type_prod<op_and, typename P::T>> operator&(P param_p) const 270 { 271 static const auto l = [left = *this, right = param_p](Context &c, Iter &start, Iter end) { 272 auto saved = start; 273 if (left(c, start, end)) { 274 start = saved; 275 return right(c, start, end); 276 } 277 start = saved; 278 return false; 279 }; 280 return l; 281 } 282 283 template <typename P> 284 next<type_prod<op_lookup, typename P::T>> operator<<(P param_p) const 285 { 286 static const auto l = [left = *this, right = param_p](Context &c, Iter &start, Iter end) { 287 auto saved1 = start; 288 if (left(c, start, end)) { 289 auto saved2 = start; 290 if (right(c, start, end)) { 291 start = saved2; 292 return true; 293 } 294 } 295 start = saved1; 296 return false; 297 }; 298 return l; 299 } 300 301 next<op_not> operator!() && 302 { 303 static const auto l = [p = *this](Context &c, Iter &start, Iter end) { 304 auto saved = start; 305 if (p(c, start, end)) { 306 start = saved; 307 return false; 308 } 309 start = saved; 310 return true; 311 }; 312 return l; 313 } 314 315 next<op_not> operator!() const & 316 { 317 static const auto l = [this](Context &c, Iter &start, Iter end) { 318 auto saved = start; 319 if ((*this)(c, start, end)) { 320 start = saved; 321 return false; 322 } 323 start = saved; 324 return true; 325 }; 326 return l; 327 } 328 329 next<op_times> operator*() && 330 { 331 static const auto l = [p = *this](Context &c, Iter &start, Iter end) { 332 while (true) { 333 auto saved = start; 334 if (!p(c, start, end)) { 335 start = saved; 336 break; 337 } 338 } 339 return true; 340 }; 341 return l; 342 } 343 344 next<op_times_ref> operator*() const & 345 { 346 static const auto l = [this](Context &c, Iter &start, Iter end) { 347 while (true) { 348 auto saved = start; 349 if (!(*this)(c, start, end)) { 350 start = saved; 351 break; 352 } 353 } 354 return true; 355 }; 356 return l; 357 } 358 }; 359 360 struct initial; 361 362 template <typename Context, typename Char, typename Iter> 363 using parser = base_parser<Context, initial, Char, Iter>; 364 365 } // namespace panda::parser 366 367 #endif // PANDA_VERIFICATION_DEBUG_PARSER_PARSER_H_ 368