1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors 2 // Licensed under the MIT License: 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 // copies of the Software, and to permit persons to whom the Software is 9 // furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 // THE SOFTWARE. 21 22 // Parser combinator framework! 23 // 24 // This file declares several functions which construct parsers, usually taking other parsers as 25 // input, thus making them parser combinators. 26 // 27 // A valid parser is any functor which takes a reference to an input cursor (defined below) as its 28 // input and returns a Maybe. The parser returns null on parse failure, or returns the parsed 29 // result on success. 30 // 31 // An "input cursor" is any type which implements the same interface as IteratorInput, below. Such 32 // a type acts as a pointer to the current input location. When a parser returns successfully, it 33 // will have updated the input cursor to point to the position just past the end of what was parsed. 34 // On failure, the cursor position is unspecified. 35 36 #pragma once 37 38 #include "../common.h" 39 #include "../memory.h" 40 #include "../array.h" 41 #include "../tuple.h" 42 #include "../vector.h" 43 44 #if _MSC_VER && _MSC_VER < 1920 && !__clang__ 45 #define KJ_MSVC_BROKEN_DECLTYPE 1 46 #endif 47 48 #if KJ_MSVC_BROKEN_DECLTYPE 49 #include <type_traits> // result_of_t 50 #endif 51 52 KJ_BEGIN_HEADER 53 54 namespace kj { 55 namespace parse { 56 57 template <typename Element, typename Iterator> 58 class IteratorInput { 59 // A parser input implementation based on an iterator range. 60 61 public: IteratorInput(Iterator begin,Iterator end)62 IteratorInput(Iterator begin, Iterator end) 63 : parent(nullptr), pos(begin), end(end), best(begin) {} IteratorInput(IteratorInput & parent)64 explicit IteratorInput(IteratorInput& parent) 65 : parent(&parent), pos(parent.pos), end(parent.end), best(parent.pos) {} ~IteratorInput()66 ~IteratorInput() { 67 if (parent != nullptr) { 68 parent->best = kj::max(kj::max(pos, best), parent->best); 69 } 70 } 71 KJ_DISALLOW_COPY(IteratorInput); 72 advanceParent()73 void advanceParent() { 74 parent->pos = pos; 75 } forgetParent()76 void forgetParent() { 77 parent = nullptr; 78 } 79 atEnd()80 bool atEnd() { return pos == end; } 81 auto current() -> decltype(*instance<Iterator>()) { 82 KJ_IREQUIRE(!atEnd()); 83 return *pos; 84 } 85 auto consume() -> decltype(*instance<Iterator>()) { 86 KJ_IREQUIRE(!atEnd()); 87 return *pos++; 88 } next()89 void next() { 90 KJ_IREQUIRE(!atEnd()); 91 ++pos; 92 } 93 getBest()94 Iterator getBest() { return kj::max(pos, best); } 95 getPosition()96 Iterator getPosition() { return pos; } 97 98 private: 99 IteratorInput* parent; 100 Iterator pos; 101 Iterator end; 102 Iterator best; // furthest we got with any sub-input 103 }; 104 105 template <typename T> struct OutputType_; 106 template <typename T> struct OutputType_<Maybe<T>> { typedef T Type; }; 107 template <typename Parser, typename Input> 108 using OutputType = typename OutputType_< 109 #if KJ_MSVC_BROKEN_DECLTYPE 110 std::result_of_t<Parser(Input)> 111 // The instance<T&>() based version below results in many compiler errors on MSVC2017. 112 #else 113 decltype(instance<Parser&>()(instance<Input&>())) 114 #endif 115 >::Type; 116 // Synonym for the output type of a parser, given the parser type and the input type. 117 118 // ======================================================================================= 119 120 template <typename Input, typename Output> 121 class ParserRef { 122 // Acts as a reference to some other parser, with simplified type. The referenced parser 123 // is polymorphic by virtual call rather than templates. For grammars of non-trivial size, 124 // it is important to inject refs into the grammar here and there to prevent the parser types 125 // from becoming ridiculous. Using too many of them can hurt performance, though. 126 127 public: 128 ParserRef(): parser(nullptr), wrapper(nullptr) {} 129 ParserRef(const ParserRef&) = default; 130 ParserRef(ParserRef&&) = default; 131 ParserRef& operator=(const ParserRef& other) = default; 132 ParserRef& operator=(ParserRef&& other) = default; 133 134 template <typename Other> 135 constexpr ParserRef(Other&& other) 136 : parser(&other), wrapper(&WrapperImplInstance<Decay<Other>>::instance) { 137 static_assert(kj::isReference<Other>(), "ParserRef should not be assigned to a temporary."); 138 } 139 140 template <typename Other> 141 inline ParserRef& operator=(Other&& other) { 142 static_assert(kj::isReference<Other>(), "ParserRef should not be assigned to a temporary."); 143 parser = &other; 144 wrapper = &WrapperImplInstance<Decay<Other>>::instance; 145 return *this; 146 } 147 148 KJ_ALWAYS_INLINE(Maybe<Output> operator()(Input& input) const) { 149 // Always inline in the hopes that this allows branch prediction to kick in so the virtual call 150 // doesn't hurt so much. 151 return wrapper->parse(parser, input); 152 } 153 154 private: 155 struct Wrapper { 156 virtual Maybe<Output> parse(const void* parser, Input& input) const = 0; 157 }; 158 template <typename ParserImpl> 159 struct WrapperImpl: public Wrapper { 160 Maybe<Output> parse(const void* parser, Input& input) const override { 161 return (*reinterpret_cast<const ParserImpl*>(parser))(input); 162 } 163 }; 164 template <typename ParserImpl> 165 struct WrapperImplInstance { 166 #if _MSC_VER && !__clang__ 167 // TODO(msvc): MSVC currently fails to initialize vtable pointers for constexpr values so 168 // we have to make this just const instead. 169 static const WrapperImpl<ParserImpl> instance; 170 #else 171 static constexpr WrapperImpl<ParserImpl> instance = WrapperImpl<ParserImpl>(); 172 #endif 173 }; 174 175 const void* parser; 176 const Wrapper* wrapper; 177 }; 178 179 template <typename Input, typename Output> 180 template <typename ParserImpl> 181 #if _MSC_VER && !__clang__ 182 const typename ParserRef<Input, Output>::template WrapperImpl<ParserImpl> 183 ParserRef<Input, Output>::WrapperImplInstance<ParserImpl>::instance = WrapperImpl<ParserImpl>(); 184 #else 185 constexpr typename ParserRef<Input, Output>::template WrapperImpl<ParserImpl> 186 ParserRef<Input, Output>::WrapperImplInstance<ParserImpl>::instance; 187 #endif 188 189 template <typename Input, typename ParserImpl> 190 constexpr ParserRef<Input, OutputType<ParserImpl, Input>> ref(ParserImpl& impl) { 191 // Constructs a ParserRef. You must specify the input type explicitly, e.g. 192 // `ref<MyInput>(myParser)`. 193 194 return ParserRef<Input, OutputType<ParserImpl, Input>>(impl); 195 } 196 197 // ------------------------------------------------------------------- 198 // any 199 // Output = one token 200 201 class Any_ { 202 public: 203 template <typename Input> 204 Maybe<Decay<decltype(instance<Input>().consume())>> operator()(Input& input) const { 205 if (input.atEnd()) { 206 return nullptr; 207 } else { 208 return input.consume(); 209 } 210 } 211 }; 212 213 constexpr Any_ any = Any_(); 214 // A parser which matches any token and simply returns it. 215 216 // ------------------------------------------------------------------- 217 // exactly() 218 // Output = Tuple<> 219 220 template <typename T> 221 class Exactly_ { 222 public: 223 explicit constexpr Exactly_(T&& expected): expected(expected) {} 224 225 template <typename Input> 226 Maybe<Tuple<>> operator()(Input& input) const { 227 if (input.atEnd() || input.current() != expected) { 228 return nullptr; 229 } else { 230 input.next(); 231 return Tuple<>(); 232 } 233 } 234 235 private: 236 T expected; 237 }; 238 239 template <typename T> 240 constexpr Exactly_<T> exactly(T&& expected) { 241 // Constructs a parser which succeeds when the input is exactly the token specified. The 242 // result is always the empty tuple. 243 244 return Exactly_<T>(kj::fwd<T>(expected)); 245 } 246 247 // ------------------------------------------------------------------- 248 // exactlyConst() 249 // Output = Tuple<> 250 251 template <typename T, T expected> 252 class ExactlyConst_ { 253 public: 254 explicit constexpr ExactlyConst_() {} 255 256 template <typename Input> 257 Maybe<Tuple<>> operator()(Input& input) const { 258 if (input.atEnd() || input.current() != expected) { 259 return nullptr; 260 } else { 261 input.next(); 262 return Tuple<>(); 263 } 264 } 265 }; 266 267 template <typename T, T expected> 268 constexpr ExactlyConst_<T, expected> exactlyConst() { 269 // Constructs a parser which succeeds when the input is exactly the token specified. The 270 // result is always the empty tuple. This parser is templated on the token value which may cause 271 // it to perform better -- or worse. Be sure to measure. 272 273 return ExactlyConst_<T, expected>(); 274 } 275 276 // ------------------------------------------------------------------- 277 // constResult() 278 279 template <typename SubParser, typename Result> 280 class ConstResult_ { 281 public: 282 explicit constexpr ConstResult_(SubParser&& subParser, Result&& result) 283 : subParser(kj::fwd<SubParser>(subParser)), result(kj::fwd<Result>(result)) {} 284 285 template <typename Input> 286 Maybe<Result> operator()(Input& input) const { 287 if (subParser(input) == nullptr) { 288 return nullptr; 289 } else { 290 return result; 291 } 292 } 293 294 private: 295 SubParser subParser; 296 Result result; 297 }; 298 299 template <typename SubParser, typename Result> 300 constexpr ConstResult_<SubParser, Result> constResult(SubParser&& subParser, Result&& result) { 301 // Constructs a parser which returns exactly `result` if `subParser` is successful. 302 return ConstResult_<SubParser, Result>(kj::fwd<SubParser>(subParser), kj::fwd<Result>(result)); 303 } 304 305 template <typename SubParser> 306 constexpr ConstResult_<SubParser, Tuple<>> discard(SubParser&& subParser) { 307 // Constructs a parser which wraps `subParser` but discards the result. 308 return constResult(kj::fwd<SubParser>(subParser), Tuple<>()); 309 } 310 311 // ------------------------------------------------------------------- 312 // sequence() 313 // Output = Flattened Tuple of outputs of sub-parsers. 314 315 template <typename... SubParsers> class Sequence_; 316 317 template <typename FirstSubParser, typename... SubParsers> 318 class Sequence_<FirstSubParser, SubParsers...> { 319 public: 320 template <typename T, typename... U> 321 explicit constexpr Sequence_(T&& firstSubParser, U&&... rest) 322 : first(kj::fwd<T>(firstSubParser)), rest(kj::fwd<U>(rest)...) {} 323 324 // TODO(msvc): The trailing return types on `operator()` and `parseNext()` expose at least two 325 // bugs in MSVC: 326 // 327 // 1. An ICE. 328 // 2. 'error C2672: 'operator __surrogate_func': no matching overloaded function found)', 329 // which crops up in numerous places when trying to build the capnp command line tools. 330 // 331 // The only workaround I found for both bugs is to omit the trailing return types and instead 332 // rely on C++14's return type deduction. 333 334 template <typename Input> 335 auto operator()(Input& input) const 336 #if !_MSC_VER || __clang__ 337 -> Maybe<decltype(tuple( 338 instance<OutputType<FirstSubParser, Input>>(), 339 instance<OutputType<SubParsers, Input>>()...))> 340 #endif 341 { 342 return parseNext(input); 343 } 344 345 template <typename Input, typename... InitialParams> 346 auto parseNext(Input& input, InitialParams&&... initialParams) const 347 #if !_MSC_VER || __clang__ 348 -> Maybe<decltype(tuple( 349 kj::fwd<InitialParams>(initialParams)..., 350 instance<OutputType<FirstSubParser, Input>>(), 351 instance<OutputType<SubParsers, Input>>()...))> 352 #endif 353 { 354 KJ_IF_MAYBE(firstResult, first(input)) { 355 return rest.parseNext(input, kj::fwd<InitialParams>(initialParams)..., 356 kj::mv(*firstResult)); 357 } else { 358 // TODO(msvc): MSVC depends on return type deduction to compile this function, so we need to 359 // help it deduce the right type on this code path. 360 return Maybe<decltype(tuple( 361 kj::fwd<InitialParams>(initialParams)..., 362 instance<OutputType<FirstSubParser, Input>>(), 363 instance<OutputType<SubParsers, Input>>()...))>{nullptr}; 364 } 365 } 366 367 private: 368 FirstSubParser first; 369 Sequence_<SubParsers...> rest; 370 }; 371 372 template <> 373 class Sequence_<> { 374 public: 375 template <typename Input> 376 Maybe<Tuple<>> operator()(Input& input) const { 377 return parseNext(input); 378 } 379 380 template <typename Input, typename... Params> 381 auto parseNext(Input& input, Params&&... params) const -> 382 Maybe<decltype(tuple(kj::fwd<Params>(params)...))> { 383 return tuple(kj::fwd<Params>(params)...); 384 } 385 }; 386 387 template <typename... SubParsers> 388 constexpr Sequence_<SubParsers...> sequence(SubParsers&&... subParsers) { 389 // Constructs a parser that executes each of the parameter parsers in sequence and returns a 390 // tuple of their results. 391 392 return Sequence_<SubParsers...>(kj::fwd<SubParsers>(subParsers)...); 393 } 394 395 // ------------------------------------------------------------------- 396 // many() 397 // Output = Array of output of sub-parser, or just a uint count if the sub-parser returns Tuple<>. 398 399 template <typename SubParser, bool atLeastOne> 400 class Many_ { 401 template <typename Input, typename Output = OutputType<SubParser, Input>> 402 struct Impl; 403 public: 404 explicit constexpr Many_(SubParser&& subParser) 405 : subParser(kj::fwd<SubParser>(subParser)) {} 406 407 template <typename Input> 408 auto operator()(Input& input) const 409 -> decltype(Impl<Input>::apply(instance<const SubParser&>(), input)); 410 411 private: 412 SubParser subParser; 413 }; 414 415 template <typename SubParser, bool atLeastOne> 416 template <typename Input, typename Output> 417 struct Many_<SubParser, atLeastOne>::Impl { 418 static Maybe<Array<Output>> apply(const SubParser& subParser, Input& input) { 419 typedef Vector<OutputType<SubParser, Input>> Results; 420 Results results; 421 422 while (!input.atEnd()) { 423 Input subInput(input); 424 425 KJ_IF_MAYBE(subResult, subParser(subInput)) { 426 subInput.advanceParent(); 427 results.add(kj::mv(*subResult)); 428 } else { 429 break; 430 } 431 } 432 433 if (atLeastOne && results.empty()) { 434 return nullptr; 435 } 436 437 return results.releaseAsArray(); 438 } 439 }; 440 441 template <typename SubParser, bool atLeastOne> 442 template <typename Input> 443 struct Many_<SubParser, atLeastOne>::Impl<Input, Tuple<>> { 444 // If the sub-parser output is Tuple<>, just return a count. 445 446 static Maybe<uint> apply(const SubParser& subParser, Input& input) { 447 uint count = 0; 448 449 while (!input.atEnd()) { 450 Input subInput(input); 451 452 KJ_IF_MAYBE(subResult, subParser(subInput)) { 453 subInput.advanceParent(); 454 ++count; 455 } else { 456 break; 457 } 458 } 459 460 if (atLeastOne && count == 0) { 461 return nullptr; 462 } 463 464 return count; 465 } 466 }; 467 468 template <typename SubParser, bool atLeastOne> 469 template <typename Input> 470 auto Many_<SubParser, atLeastOne>::operator()(Input& input) const 471 -> decltype(Impl<Input>::apply(instance<const SubParser&>(), input)) { 472 return Impl<Input, OutputType<SubParser, Input>>::apply(subParser, input); 473 } 474 475 template <typename SubParser> 476 constexpr Many_<SubParser, false> many(SubParser&& subParser) { 477 // Constructs a parser that repeatedly executes the given parser until it fails, returning an 478 // Array of the results (or a uint count if `subParser` returns an empty tuple). 479 return Many_<SubParser, false>(kj::fwd<SubParser>(subParser)); 480 } 481 482 template <typename SubParser> 483 constexpr Many_<SubParser, true> oneOrMore(SubParser&& subParser) { 484 // Like `many()` but the parser must parse at least one item to be successful. 485 return Many_<SubParser, true>(kj::fwd<SubParser>(subParser)); 486 } 487 488 // ------------------------------------------------------------------- 489 // times() 490 // Output = Array of output of sub-parser, or Tuple<> if sub-parser returns Tuple<>. 491 492 template <typename SubParser> 493 class Times_ { 494 template <typename Input, typename Output = OutputType<SubParser, Input>> 495 struct Impl; 496 public: 497 explicit constexpr Times_(SubParser&& subParser, uint count) 498 : subParser(kj::fwd<SubParser>(subParser)), count(count) {} 499 500 template <typename Input> 501 auto operator()(Input& input) const 502 -> decltype(Impl<Input>::apply(instance<const SubParser&>(), instance<uint>(), input)); 503 504 private: 505 SubParser subParser; 506 uint count; 507 }; 508 509 template <typename SubParser> 510 template <typename Input, typename Output> 511 struct Times_<SubParser>::Impl { 512 static Maybe<Array<Output>> apply(const SubParser& subParser, uint count, Input& input) { 513 auto results = heapArrayBuilder<OutputType<SubParser, Input>>(count); 514 515 while (results.size() < count) { 516 if (input.atEnd()) { 517 return nullptr; 518 } else KJ_IF_MAYBE(subResult, subParser(input)) { 519 results.add(kj::mv(*subResult)); 520 } else { 521 return nullptr; 522 } 523 } 524 525 return results.finish(); 526 } 527 }; 528 529 template <typename SubParser> 530 template <typename Input> 531 struct Times_<SubParser>::Impl<Input, Tuple<>> { 532 // If the sub-parser output is Tuple<>, just return a count. 533 534 static Maybe<Tuple<>> apply(const SubParser& subParser, uint count, Input& input) { 535 uint actualCount = 0; 536 537 while (actualCount < count) { 538 if (input.atEnd()) { 539 return nullptr; 540 } else KJ_IF_MAYBE(subResult, subParser(input)) { 541 ++actualCount; 542 } else { 543 return nullptr; 544 } 545 } 546 547 return tuple(); 548 } 549 }; 550 551 template <typename SubParser> 552 template <typename Input> 553 auto Times_<SubParser>::operator()(Input& input) const 554 -> decltype(Impl<Input>::apply(instance<const SubParser&>(), instance<uint>(), input)) { 555 return Impl<Input, OutputType<SubParser, Input>>::apply(subParser, count, input); 556 } 557 558 template <typename SubParser> 559 constexpr Times_<SubParser> times(SubParser&& subParser, uint count) { 560 // Constructs a parser that repeats the subParser exactly `count` times. 561 return Times_<SubParser>(kj::fwd<SubParser>(subParser), count); 562 } 563 564 // ------------------------------------------------------------------- 565 // optional() 566 // Output = Maybe<output of sub-parser> 567 568 template <typename SubParser> 569 class Optional_ { 570 public: 571 explicit constexpr Optional_(SubParser&& subParser) 572 : subParser(kj::fwd<SubParser>(subParser)) {} 573 574 template <typename Input> 575 Maybe<Maybe<OutputType<SubParser, Input>>> operator()(Input& input) const { 576 typedef Maybe<OutputType<SubParser, Input>> Result; 577 578 Input subInput(input); 579 KJ_IF_MAYBE(subResult, subParser(subInput)) { 580 subInput.advanceParent(); 581 return Result(kj::mv(*subResult)); 582 } else { 583 return Result(nullptr); 584 } 585 } 586 587 private: 588 SubParser subParser; 589 }; 590 591 template <typename SubParser> 592 constexpr Optional_<SubParser> optional(SubParser&& subParser) { 593 // Constructs a parser that accepts zero or one of the given sub-parser, returning a Maybe 594 // of the sub-parser's result. 595 return Optional_<SubParser>(kj::fwd<SubParser>(subParser)); 596 } 597 598 // ------------------------------------------------------------------- 599 // oneOf() 600 // All SubParsers must have same output type, which becomes the output type of the 601 // OneOfParser. 602 603 template <typename... SubParsers> 604 class OneOf_; 605 606 template <typename FirstSubParser, typename... SubParsers> 607 class OneOf_<FirstSubParser, SubParsers...> { 608 public: 609 explicit constexpr OneOf_(FirstSubParser&& firstSubParser, SubParsers&&... rest) 610 : first(kj::fwd<FirstSubParser>(firstSubParser)), rest(kj::fwd<SubParsers>(rest)...) {} 611 612 template <typename Input> 613 Maybe<OutputType<FirstSubParser, Input>> operator()(Input& input) const { 614 { 615 Input subInput(input); 616 Maybe<OutputType<FirstSubParser, Input>> firstResult = first(subInput); 617 618 if (firstResult != nullptr) { 619 subInput.advanceParent(); 620 return kj::mv(firstResult); 621 } 622 } 623 624 // Hoping for some tail recursion here... 625 return rest(input); 626 } 627 628 private: 629 FirstSubParser first; 630 OneOf_<SubParsers...> rest; 631 }; 632 633 template <> 634 class OneOf_<> { 635 public: 636 template <typename Input> 637 decltype(nullptr) operator()(Input& input) const { 638 return nullptr; 639 } 640 }; 641 642 template <typename... SubParsers> 643 constexpr OneOf_<SubParsers...> oneOf(SubParsers&&... parsers) { 644 // Constructs a parser that accepts one of a set of options. The parser behaves as the first 645 // sub-parser in the list which returns successfully. All of the sub-parsers must return the 646 // same type. 647 return OneOf_<SubParsers...>(kj::fwd<SubParsers>(parsers)...); 648 } 649 650 // ------------------------------------------------------------------- 651 // transform() 652 // Output = Result of applying transform functor to input value. If input is a tuple, it is 653 // unpacked to form the transformation parameters. 654 655 template <typename Position> 656 struct Span { 657 public: 658 inline const Position& begin() const { return begin_; } 659 inline const Position& end() const { return end_; } 660 661 Span() = default; 662 inline constexpr Span(Position&& begin, Position&& end): begin_(mv(begin)), end_(mv(end)) {} 663 664 private: 665 Position begin_; 666 Position end_; 667 }; 668 669 template <typename Position> 670 constexpr Span<Decay<Position>> span(Position&& start, Position&& end) { 671 return Span<Decay<Position>>(kj::fwd<Position>(start), kj::fwd<Position>(end)); 672 } 673 674 template <typename SubParser, typename TransformFunc> 675 class Transform_ { 676 public: 677 explicit constexpr Transform_(SubParser&& subParser, TransformFunc&& transform) 678 : subParser(kj::fwd<SubParser>(subParser)), transform(kj::fwd<TransformFunc>(transform)) {} 679 680 template <typename Input> 681 Maybe<decltype(kj::apply(instance<TransformFunc&>(), 682 instance<OutputType<SubParser, Input>&&>()))> 683 operator()(Input& input) const { 684 KJ_IF_MAYBE(subResult, subParser(input)) { 685 return kj::apply(transform, kj::mv(*subResult)); 686 } else { 687 return nullptr; 688 } 689 } 690 691 private: 692 SubParser subParser; 693 TransformFunc transform; 694 }; 695 696 template <typename SubParser, typename TransformFunc> 697 class TransformOrReject_ { 698 public: 699 explicit constexpr TransformOrReject_(SubParser&& subParser, TransformFunc&& transform) 700 : subParser(kj::fwd<SubParser>(subParser)), transform(kj::fwd<TransformFunc>(transform)) {} 701 702 template <typename Input> 703 decltype(kj::apply(instance<TransformFunc&>(), instance<OutputType<SubParser, Input>&&>())) 704 operator()(Input& input) const { 705 KJ_IF_MAYBE(subResult, subParser(input)) { 706 return kj::apply(transform, kj::mv(*subResult)); 707 } else { 708 return nullptr; 709 } 710 } 711 712 private: 713 SubParser subParser; 714 TransformFunc transform; 715 }; 716 717 template <typename SubParser, typename TransformFunc> 718 class TransformWithLocation_ { 719 public: 720 explicit constexpr TransformWithLocation_(SubParser&& subParser, TransformFunc&& transform) 721 : subParser(kj::fwd<SubParser>(subParser)), transform(kj::fwd<TransformFunc>(transform)) {} 722 723 template <typename Input> 724 Maybe<decltype(kj::apply(instance<TransformFunc&>(), 725 instance<Span<Decay<decltype(instance<Input&>().getPosition())>>>(), 726 instance<OutputType<SubParser, Input>&&>()))> 727 operator()(Input& input) const { 728 auto start = input.getPosition(); 729 KJ_IF_MAYBE(subResult, subParser(input)) { 730 return kj::apply(transform, Span<decltype(start)>(kj::mv(start), input.getPosition()), 731 kj::mv(*subResult)); 732 } else { 733 return nullptr; 734 } 735 } 736 737 private: 738 SubParser subParser; 739 TransformFunc transform; 740 }; 741 742 template <typename SubParser, typename TransformFunc> 743 constexpr Transform_<SubParser, TransformFunc> transform( 744 SubParser&& subParser, TransformFunc&& functor) { 745 // Constructs a parser which executes some other parser and then transforms the result by invoking 746 // `functor` on it. Typically `functor` is a lambda. It is invoked using `kj::apply`, 747 // meaning tuples will be unpacked as arguments. 748 return Transform_<SubParser, TransformFunc>( 749 kj::fwd<SubParser>(subParser), kj::fwd<TransformFunc>(functor)); 750 } 751 752 template <typename SubParser, typename TransformFunc> 753 constexpr TransformOrReject_<SubParser, TransformFunc> transformOrReject( 754 SubParser&& subParser, TransformFunc&& functor) { 755 // Like `transform()` except that `functor` returns a `Maybe`. If it returns null, parsing fails, 756 // otherwise the parser's result is the content of the `Maybe`. 757 return TransformOrReject_<SubParser, TransformFunc>( 758 kj::fwd<SubParser>(subParser), kj::fwd<TransformFunc>(functor)); 759 } 760 761 template <typename SubParser, typename TransformFunc> 762 constexpr TransformWithLocation_<SubParser, TransformFunc> transformWithLocation( 763 SubParser&& subParser, TransformFunc&& functor) { 764 // Like `transform` except that `functor` also takes a `Span` as its first parameter specifying 765 // the location of the parsed content. The span's position type is whatever the parser input's 766 // getPosition() returns. 767 return TransformWithLocation_<SubParser, TransformFunc>( 768 kj::fwd<SubParser>(subParser), kj::fwd<TransformFunc>(functor)); 769 } 770 771 // ------------------------------------------------------------------- 772 // notLookingAt() 773 // Fails if the given parser succeeds at the current location. 774 775 template <typename SubParser> 776 class NotLookingAt_ { 777 public: 778 explicit constexpr NotLookingAt_(SubParser&& subParser) 779 : subParser(kj::fwd<SubParser>(subParser)) {} 780 781 template <typename Input> 782 Maybe<Tuple<>> operator()(Input& input) const { 783 Input subInput(input); 784 subInput.forgetParent(); 785 if (subParser(subInput) == nullptr) { 786 return Tuple<>(); 787 } else { 788 return nullptr; 789 } 790 } 791 792 private: 793 SubParser subParser; 794 }; 795 796 template <typename SubParser> 797 constexpr NotLookingAt_<SubParser> notLookingAt(SubParser&& subParser) { 798 // Constructs a parser which fails at any position where the given parser succeeds. Otherwise, 799 // it succeeds without consuming any input and returns an empty tuple. 800 return NotLookingAt_<SubParser>(kj::fwd<SubParser>(subParser)); 801 } 802 803 // ------------------------------------------------------------------- 804 // endOfInput() 805 // Output = Tuple<>, only succeeds if at end-of-input 806 807 class EndOfInput_ { 808 public: 809 template <typename Input> 810 Maybe<Tuple<>> operator()(Input& input) const { 811 if (input.atEnd()) { 812 return Tuple<>(); 813 } else { 814 return nullptr; 815 } 816 } 817 }; 818 819 constexpr EndOfInput_ endOfInput = EndOfInput_(); 820 // A parser that succeeds only if it is called with no input. 821 822 } // namespace parse 823 } // namespace kj 824 825 KJ_END_HEADER 826