comparison osx/include/kj/parse/common.h @ 62:0994c39f1e94

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