You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					825 lines
				
				26 KiB
			
		
		
			
		
	
	
					825 lines
				
				26 KiB
			| 
								 
											6 years ago
										 
									 | 
							
								// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
							 | 
						||
| 
								 | 
							
								// Licensed under the MIT License:
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Permission is hereby granted, free of charge, to any person obtaining a copy
							 | 
						||
| 
								 | 
							
								// of this software and associated documentation files (the "Software"), to deal
							 | 
						||
| 
								 | 
							
								// in the Software without restriction, including without limitation the rights
							 | 
						||
| 
								 | 
							
								// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
							 | 
						||
| 
								 | 
							
								// copies of the Software, and to permit persons to whom the Software is
							 | 
						||
| 
								 | 
							
								// furnished to do so, subject to the following conditions:
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// The above copyright notice and this permission notice shall be included in
							 | 
						||
| 
								 | 
							
								// all copies or substantial portions of the Software.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
							 | 
						||
| 
								 | 
							
								// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
							 | 
						||
| 
								 | 
							
								// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
							 | 
						||
| 
								 | 
							
								// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
							 | 
						||
| 
								 | 
							
								// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
							 | 
						||
| 
								 | 
							
								// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
							 | 
						||
| 
								 | 
							
								// THE SOFTWARE.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Parser combinator framework!
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// This file declares several functions which construct parsers, usually taking other parsers as
							 | 
						||
| 
								 | 
							
								// input, thus making them parser combinators.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// A valid parser is any functor which takes a reference to an input cursor (defined below) as its
							 | 
						||
| 
								 | 
							
								// input and returns a Maybe.  The parser returns null on parse failure, or returns the parsed
							 | 
						||
| 
								 | 
							
								// result on success.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// An "input cursor" is any type which implements the same interface as IteratorInput, below.  Such
							 | 
						||
| 
								 | 
							
								// a type acts as a pointer to the current input location.  When a parser returns successfully, it
							 | 
						||
| 
								 | 
							
								// will have updated the input cursor to point to the position just past the end of what was parsed.
							 | 
						||
| 
								 | 
							
								// On failure, the cursor position is unspecified.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef KJ_PARSE_COMMON_H_
							 | 
						||
| 
								 | 
							
								#define KJ_PARSE_COMMON_H_
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined(__GNUC__) && !KJ_HEADER_WARNINGS
							 | 
						||
| 
								 | 
							
								#pragma GCC system_header
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "../common.h"
							 | 
						||
| 
								 | 
							
								#include "../memory.h"
							 | 
						||
| 
								 | 
							
								#include "../array.h"
							 | 
						||
| 
								 | 
							
								#include "../tuple.h"
							 | 
						||
| 
								 | 
							
								#include "../vector.h"
							 | 
						||
| 
								 | 
							
								#if _MSC_VER
							 | 
						||
| 
								 | 
							
								#include <type_traits>  // result_of_t
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace kj {
							 | 
						||
| 
								 | 
							
								namespace parse {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename Element, typename Iterator>
							 | 
						||
| 
								 | 
							
								class IteratorInput {
							 | 
						||
| 
								 | 
							
								  // A parser input implementation based on an iterator range.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  IteratorInput(Iterator begin, Iterator end)
							 | 
						||
| 
								 | 
							
								      : parent(nullptr), pos(begin), end(end), best(begin) {}
							 | 
						||
| 
								 | 
							
								  explicit IteratorInput(IteratorInput& parent)
							 | 
						||
| 
								 | 
							
								      : parent(&parent), pos(parent.pos), end(parent.end), best(parent.pos) {}
							 | 
						||
| 
								 | 
							
								  ~IteratorInput() {
							 | 
						||
| 
								 | 
							
								    if (parent != nullptr) {
							 | 
						||
| 
								 | 
							
								      parent->best = kj::max(kj::max(pos, best), parent->best);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  KJ_DISALLOW_COPY(IteratorInput);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  void advanceParent() {
							 | 
						||
| 
								 | 
							
								    parent->pos = pos;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  void forgetParent() {
							 | 
						||
| 
								 | 
							
								    parent = nullptr;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  bool atEnd() { return pos == end; }
							 | 
						||
| 
								 | 
							
								  auto current() -> decltype(*instance<Iterator>()) {
							 | 
						||
| 
								 | 
							
								    KJ_IREQUIRE(!atEnd());
							 | 
						||
| 
								 | 
							
								    return *pos;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  auto consume() -> decltype(*instance<Iterator>()) {
							 | 
						||
| 
								 | 
							
								    KJ_IREQUIRE(!atEnd());
							 | 
						||
| 
								 | 
							
								    return *pos++;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  void next() {
							 | 
						||
| 
								 | 
							
								    KJ_IREQUIRE(!atEnd());
							 | 
						||
| 
								 | 
							
								    ++pos;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  Iterator getBest() { return kj::max(pos, best); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  Iterator getPosition() { return pos; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								  IteratorInput* parent;
							 | 
						||
| 
								 | 
							
								  Iterator pos;
							 | 
						||
| 
								 | 
							
								  Iterator end;
							 | 
						||
| 
								 | 
							
								  Iterator best;  // furthest we got with any sub-input
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename T> struct OutputType_;
							 | 
						||
| 
								 | 
							
								template <typename T> struct OutputType_<Maybe<T>> { typedef T Type; };
							 | 
						||
| 
								 | 
							
								template <typename Parser, typename Input>
							 | 
						||
| 
								 | 
							
								using OutputType = typename OutputType_<
							 | 
						||
| 
								 | 
							
								#if _MSC_VER
							 | 
						||
| 
								 | 
							
								    std::result_of_t<Parser(Input)>
							 | 
						||
| 
								 | 
							
								    // The instance<T&>() based version below results in:
							 | 
						||
| 
								 | 
							
								    //   C2064: term does not evaluate to a function taking 1 arguments
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    decltype(instance<Parser&>()(instance<Input&>()))
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    >::Type;
							 | 
						||
| 
								 | 
							
								// Synonym for the output type of a parser, given the parser type and the input type.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// =======================================================================================
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename Input, typename Output>
							 | 
						||
| 
								 | 
							
								class ParserRef {
							 | 
						||
| 
								 | 
							
								  // Acts as a reference to some other parser, with simplified type.  The referenced parser
							 | 
						||
| 
								 | 
							
								  // is polymorphic by virtual call rather than templates.  For grammars of non-trivial size,
							 | 
						||
| 
								 | 
							
								  // it is important to inject refs into the grammar here and there to prevent the parser types
							 | 
						||
| 
								 | 
							
								  // from becoming ridiculous.  Using too many of them can hurt performance, though.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  ParserRef(): parser(nullptr), wrapper(nullptr) {}
							 | 
						||
| 
								 | 
							
								  ParserRef(const ParserRef&) = default;
							 | 
						||
| 
								 | 
							
								  ParserRef(ParserRef&&) = default;
							 | 
						||
| 
								 | 
							
								  ParserRef& operator=(const ParserRef& other) = default;
							 | 
						||
| 
								 | 
							
								  ParserRef& operator=(ParserRef&& other) = default;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Other>
							 | 
						||
| 
								 | 
							
								  constexpr ParserRef(Other&& other)
							 | 
						||
| 
								 | 
							
								      : parser(&other), wrapper(&WrapperImplInstance<Decay<Other>>::instance) {
							 | 
						||
| 
								 | 
							
								    static_assert(kj::isReference<Other>(), "ParserRef should not be assigned to a temporary.");
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Other>
							 | 
						||
| 
								 | 
							
								  inline ParserRef& operator=(Other&& other) {
							 | 
						||
| 
								 | 
							
								    static_assert(kj::isReference<Other>(), "ParserRef should not be assigned to a temporary.");
							 | 
						||
| 
								 | 
							
								    parser = &other;
							 | 
						||
| 
								 | 
							
								    wrapper = &WrapperImplInstance<Decay<Other>>::instance;
							 | 
						||
| 
								 | 
							
								    return *this;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  KJ_ALWAYS_INLINE(Maybe<Output> operator()(Input& input) const) {
							 | 
						||
| 
								 | 
							
								    // Always inline in the hopes that this allows branch prediction to kick in so the virtual call
							 | 
						||
| 
								 | 
							
								    // doesn't hurt so much.
							 | 
						||
| 
								 | 
							
								    return wrapper->parse(parser, input);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								  struct Wrapper {
							 | 
						||
| 
								 | 
							
								    virtual Maybe<Output> parse(const void* parser, Input& input) const = 0;
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								  template <typename ParserImpl>
							 | 
						||
| 
								 | 
							
								  struct WrapperImpl: public Wrapper {
							 | 
						||
| 
								 | 
							
								    Maybe<Output> parse(const void* parser, Input& input) const override {
							 | 
						||
| 
								 | 
							
								      return (*reinterpret_cast<const ParserImpl*>(parser))(input);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								  template <typename ParserImpl>
							 | 
						||
| 
								 | 
							
								  struct WrapperImplInstance {
							 | 
						||
| 
								 | 
							
								#if _MSC_VER
							 | 
						||
| 
								 | 
							
								    // TODO(msvc): MSVC currently fails to initialize vtable pointers for constexpr values so
							 | 
						||
| 
								 | 
							
								    //   we have to make this just const instead.
							 | 
						||
| 
								 | 
							
								    static const WrapperImpl<ParserImpl> instance;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    static constexpr WrapperImpl<ParserImpl> instance = WrapperImpl<ParserImpl>();
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const void* parser;
							 | 
						||
| 
								 | 
							
								  const Wrapper* wrapper;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename Input, typename Output>
							 | 
						||
| 
								 | 
							
								template <typename ParserImpl>
							 | 
						||
| 
								 | 
							
								#if _MSC_VER
							 | 
						||
| 
								 | 
							
								const typename ParserRef<Input, Output>::template WrapperImpl<ParserImpl>
							 | 
						||
| 
								 | 
							
								ParserRef<Input, Output>::WrapperImplInstance<ParserImpl>::instance = WrapperImpl<ParserImpl>();
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								constexpr typename ParserRef<Input, Output>::template WrapperImpl<ParserImpl>
							 | 
						||
| 
								 | 
							
								ParserRef<Input, Output>::WrapperImplInstance<ParserImpl>::instance;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename Input, typename ParserImpl>
							 | 
						||
| 
								 | 
							
								constexpr ParserRef<Input, OutputType<ParserImpl, Input>> ref(ParserImpl& impl) {
							 | 
						||
| 
								 | 
							
								  // Constructs a ParserRef.  You must specify the input type explicitly, e.g.
							 | 
						||
| 
								 | 
							
								  // `ref<MyInput>(myParser)`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return ParserRef<Input, OutputType<ParserImpl, Input>>(impl);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// any
							 | 
						||
| 
								 | 
							
								// Output = one token
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Any_ {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  Maybe<Decay<decltype(instance<Input>().consume())>> operator()(Input& input) const {
							 | 
						||
| 
								 | 
							
								    if (input.atEnd()) {
							 | 
						||
| 
								 | 
							
								      return nullptr;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      return input.consume();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								constexpr Any_ any = Any_();
							 | 
						||
| 
								 | 
							
								// A parser which matches any token and simply returns it.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// exactly()
							 | 
						||
| 
								 | 
							
								// Output = Tuple<>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename T>
							 | 
						||
| 
								 | 
							
								class Exactly_ {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  explicit constexpr Exactly_(T&& expected): expected(expected) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  Maybe<Tuple<>> operator()(Input& input) const {
							 | 
						||
| 
								 | 
							
								    if (input.atEnd() || input.current() != expected) {
							 | 
						||
| 
								 | 
							
								      return nullptr;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      input.next();
							 | 
						||
| 
								 | 
							
								      return Tuple<>();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								  T expected;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename T>
							 | 
						||
| 
								 | 
							
								constexpr Exactly_<T> exactly(T&& expected) {
							 | 
						||
| 
								 | 
							
								  // Constructs a parser which succeeds when the input is exactly the token specified.  The
							 | 
						||
| 
								 | 
							
								  // result is always the empty tuple.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return Exactly_<T>(kj::fwd<T>(expected));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// exactlyConst()
							 | 
						||
| 
								 | 
							
								// Output = Tuple<>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename T, T expected>
							 | 
						||
| 
								 | 
							
								class ExactlyConst_ {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  explicit constexpr ExactlyConst_() {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  Maybe<Tuple<>> operator()(Input& input) const {
							 | 
						||
| 
								 | 
							
								    if (input.atEnd() || input.current() != expected) {
							 | 
						||
| 
								 | 
							
								      return nullptr;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      input.next();
							 | 
						||
| 
								 | 
							
								      return Tuple<>();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename T, T expected>
							 | 
						||
| 
								 | 
							
								constexpr ExactlyConst_<T, expected> exactlyConst() {
							 | 
						||
| 
								 | 
							
								  // Constructs a parser which succeeds when the input is exactly the token specified.  The
							 | 
						||
| 
								 | 
							
								  // result is always the empty tuple.  This parser is templated on the token value which may cause
							 | 
						||
| 
								 | 
							
								  // it to perform better -- or worse.  Be sure to measure.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return ExactlyConst_<T, expected>();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// constResult()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser, typename Result>
							 | 
						||
| 
								 | 
							
								class ConstResult_ {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  explicit constexpr ConstResult_(SubParser&& subParser, Result&& result)
							 | 
						||
| 
								 | 
							
								      : subParser(kj::fwd<SubParser>(subParser)), result(kj::fwd<Result>(result)) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  Maybe<Result> operator()(Input& input) const {
							 | 
						||
| 
								 | 
							
								    if (subParser(input) == nullptr) {
							 | 
						||
| 
								 | 
							
								      return nullptr;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      return result;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								  SubParser subParser;
							 | 
						||
| 
								 | 
							
								  Result result;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser, typename Result>
							 | 
						||
| 
								 | 
							
								constexpr ConstResult_<SubParser, Result> constResult(SubParser&& subParser, Result&& result) {
							 | 
						||
| 
								 | 
							
								  // Constructs a parser which returns exactly `result` if `subParser` is successful.
							 | 
						||
| 
								 | 
							
								  return ConstResult_<SubParser, Result>(kj::fwd<SubParser>(subParser), kj::fwd<Result>(result));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser>
							 | 
						||
| 
								 | 
							
								constexpr ConstResult_<SubParser, Tuple<>> discard(SubParser&& subParser) {
							 | 
						||
| 
								 | 
							
								  // Constructs a parser which wraps `subParser` but discards the result.
							 | 
						||
| 
								 | 
							
								  return constResult(kj::fwd<SubParser>(subParser), Tuple<>());
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// sequence()
							 | 
						||
| 
								 | 
							
								// Output = Flattened Tuple of outputs of sub-parsers.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename... SubParsers> class Sequence_;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename FirstSubParser, typename... SubParsers>
							 | 
						||
| 
								 | 
							
								class Sequence_<FirstSubParser, SubParsers...> {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  template <typename T, typename... U>
							 | 
						||
| 
								 | 
							
								  explicit constexpr Sequence_(T&& firstSubParser, U&&... rest)
							 | 
						||
| 
								 | 
							
								      : first(kj::fwd<T>(firstSubParser)), rest(kj::fwd<U>(rest)...) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // TODO(msvc): The trailing return types on `operator()` and `parseNext()` expose at least two
							 | 
						||
| 
								 | 
							
								  //   bugs in MSVC:
							 | 
						||
| 
								 | 
							
								  //
							 | 
						||
| 
								 | 
							
								  //     1. An ICE.
							 | 
						||
| 
								 | 
							
								  //     2. 'error C2672: 'operator __surrogate_func': no matching overloaded function found)',
							 | 
						||
| 
								 | 
							
								  //        which crops up in numerous places when trying to build the capnp command line tools.
							 | 
						||
| 
								 | 
							
								  //
							 | 
						||
| 
								 | 
							
								  //   The only workaround I found for both bugs is to omit the trailing return types and instead
							 | 
						||
| 
								 | 
							
								  //   rely on C++14's return type deduction.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  auto operator()(Input& input) const
							 | 
						||
| 
								 | 
							
								#ifndef _MSC_VER
							 | 
						||
| 
								 | 
							
								      -> Maybe<decltype(tuple(
							 | 
						||
| 
								 | 
							
								          instance<OutputType<FirstSubParser, Input>>(),
							 | 
						||
| 
								 | 
							
								          instance<OutputType<SubParsers, Input>>()...))>
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    return parseNext(input);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Input, typename... InitialParams>
							 | 
						||
| 
								 | 
							
								  auto parseNext(Input& input, InitialParams&&... initialParams) const
							 | 
						||
| 
								 | 
							
								#ifndef _MSC_VER
							 | 
						||
| 
								 | 
							
								      -> Maybe<decltype(tuple(
							 | 
						||
| 
								 | 
							
								          kj::fwd<InitialParams>(initialParams)...,
							 | 
						||
| 
								 | 
							
								          instance<OutputType<FirstSubParser, Input>>(),
							 | 
						||
| 
								 | 
							
								          instance<OutputType<SubParsers, Input>>()...))>
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    KJ_IF_MAYBE(firstResult, first(input)) {
							 | 
						||
| 
								 | 
							
								      return rest.parseNext(input, kj::fwd<InitialParams>(initialParams)...,
							 | 
						||
| 
								 | 
							
								                            kj::mv(*firstResult));
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      // TODO(msvc): MSVC depends on return type deduction to compile this function, so we need to
							 | 
						||
| 
								 | 
							
								      //   help it deduce the right type on this code path.
							 | 
						||
| 
								 | 
							
								      return Maybe<decltype(tuple(
							 | 
						||
| 
								 | 
							
								          kj::fwd<InitialParams>(initialParams)...,
							 | 
						||
| 
								 | 
							
								          instance<OutputType<FirstSubParser, Input>>(),
							 | 
						||
| 
								 | 
							
								          instance<OutputType<SubParsers, Input>>()...))>{nullptr};
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								  FirstSubParser first;
							 | 
						||
| 
								 | 
							
								  Sequence_<SubParsers...> rest;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <>
							 | 
						||
| 
								 | 
							
								class Sequence_<> {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  Maybe<Tuple<>> operator()(Input& input) const {
							 | 
						||
| 
								 | 
							
								    return parseNext(input);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Input, typename... Params>
							 | 
						||
| 
								 | 
							
								  auto parseNext(Input& input, Params&&... params) const ->
							 | 
						||
| 
								 | 
							
								      Maybe<decltype(tuple(kj::fwd<Params>(params)...))> {
							 | 
						||
| 
								 | 
							
								    return tuple(kj::fwd<Params>(params)...);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename... SubParsers>
							 | 
						||
| 
								 | 
							
								constexpr Sequence_<SubParsers...> sequence(SubParsers&&... subParsers) {
							 | 
						||
| 
								 | 
							
								  // Constructs a parser that executes each of the parameter parsers in sequence and returns a
							 | 
						||
| 
								 | 
							
								  // tuple of their results.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return Sequence_<SubParsers...>(kj::fwd<SubParsers>(subParsers)...);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// many()
							 | 
						||
| 
								 | 
							
								// Output = Array of output of sub-parser, or just a uint count if the sub-parser returns Tuple<>.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser, bool atLeastOne>
							 | 
						||
| 
								 | 
							
								class Many_ {
							 | 
						||
| 
								 | 
							
								  template <typename Input, typename Output = OutputType<SubParser, Input>>
							 | 
						||
| 
								 | 
							
								  struct Impl;
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  explicit constexpr Many_(SubParser&& subParser)
							 | 
						||
| 
								 | 
							
								      : subParser(kj::fwd<SubParser>(subParser)) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  auto operator()(Input& input) const
							 | 
						||
| 
								 | 
							
								      -> decltype(Impl<Input>::apply(instance<const SubParser&>(), input));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								  SubParser subParser;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser, bool atLeastOne>
							 | 
						||
| 
								 | 
							
								template <typename Input, typename Output>
							 | 
						||
| 
								 | 
							
								struct Many_<SubParser, atLeastOne>::Impl {
							 | 
						||
| 
								 | 
							
								  static Maybe<Array<Output>> apply(const SubParser& subParser, Input& input) {
							 | 
						||
| 
								 | 
							
								    typedef Vector<OutputType<SubParser, Input>> Results;
							 | 
						||
| 
								 | 
							
								    Results results;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while (!input.atEnd()) {
							 | 
						||
| 
								 | 
							
								      Input subInput(input);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      KJ_IF_MAYBE(subResult, subParser(subInput)) {
							 | 
						||
| 
								 | 
							
								        subInput.advanceParent();
							 | 
						||
| 
								 | 
							
								        results.add(kj::mv(*subResult));
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (atLeastOne && results.empty()) {
							 | 
						||
| 
								 | 
							
								      return nullptr;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return results.releaseAsArray();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser, bool atLeastOne>
							 | 
						||
| 
								 | 
							
								template <typename Input>
							 | 
						||
| 
								 | 
							
								struct Many_<SubParser, atLeastOne>::Impl<Input, Tuple<>> {
							 | 
						||
| 
								 | 
							
								  // If the sub-parser output is Tuple<>, just return a count.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  static Maybe<uint> apply(const SubParser& subParser, Input& input) {
							 | 
						||
| 
								 | 
							
								    uint count = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while (!input.atEnd()) {
							 | 
						||
| 
								 | 
							
								      Input subInput(input);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      KJ_IF_MAYBE(subResult, subParser(subInput)) {
							 | 
						||
| 
								 | 
							
								        subInput.advanceParent();
							 | 
						||
| 
								 | 
							
								        ++count;
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (atLeastOne && count == 0) {
							 | 
						||
| 
								 | 
							
								      return nullptr;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return count;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser, bool atLeastOne>
							 | 
						||
| 
								 | 
							
								template <typename Input>
							 | 
						||
| 
								 | 
							
								auto Many_<SubParser, atLeastOne>::operator()(Input& input) const
							 | 
						||
| 
								 | 
							
								    -> decltype(Impl<Input>::apply(instance<const SubParser&>(), input)) {
							 | 
						||
| 
								 | 
							
								  return Impl<Input, OutputType<SubParser, Input>>::apply(subParser, input);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser>
							 | 
						||
| 
								 | 
							
								constexpr Many_<SubParser, false> many(SubParser&& subParser) {
							 | 
						||
| 
								 | 
							
								  // Constructs a parser that repeatedly executes the given parser until it fails, returning an
							 | 
						||
| 
								 | 
							
								  // Array of the results (or a uint count if `subParser` returns an empty tuple).
							 | 
						||
| 
								 | 
							
								  return Many_<SubParser, false>(kj::fwd<SubParser>(subParser));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser>
							 | 
						||
| 
								 | 
							
								constexpr Many_<SubParser, true> oneOrMore(SubParser&& subParser) {
							 | 
						||
| 
								 | 
							
								  // Like `many()` but the parser must parse at least one item to be successful.
							 | 
						||
| 
								 | 
							
								  return Many_<SubParser, true>(kj::fwd<SubParser>(subParser));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// times()
							 | 
						||
| 
								 | 
							
								// Output = Array of output of sub-parser, or Tuple<> if sub-parser returns Tuple<>.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser>
							 | 
						||
| 
								 | 
							
								class Times_ {
							 | 
						||
| 
								 | 
							
								  template <typename Input, typename Output = OutputType<SubParser, Input>>
							 | 
						||
| 
								 | 
							
								  struct Impl;
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  explicit constexpr Times_(SubParser&& subParser, uint count)
							 | 
						||
| 
								 | 
							
								      : subParser(kj::fwd<SubParser>(subParser)), count(count) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  auto operator()(Input& input) const
							 | 
						||
| 
								 | 
							
								      -> decltype(Impl<Input>::apply(instance<const SubParser&>(), instance<uint>(), input));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								  SubParser subParser;
							 | 
						||
| 
								 | 
							
								  uint count;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser>
							 | 
						||
| 
								 | 
							
								template <typename Input, typename Output>
							 | 
						||
| 
								 | 
							
								struct Times_<SubParser>::Impl {
							 | 
						||
| 
								 | 
							
								  static Maybe<Array<Output>> apply(const SubParser& subParser, uint count, Input& input) {
							 | 
						||
| 
								 | 
							
								    auto results = heapArrayBuilder<OutputType<SubParser, Input>>(count);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while (results.size() < count) {
							 | 
						||
| 
								 | 
							
								      if (input.atEnd()) {
							 | 
						||
| 
								 | 
							
								        return nullptr;
							 | 
						||
| 
								 | 
							
								      } else KJ_IF_MAYBE(subResult, subParser(input)) {
							 | 
						||
| 
								 | 
							
								        results.add(kj::mv(*subResult));
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        return nullptr;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return results.finish();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser>
							 | 
						||
| 
								 | 
							
								template <typename Input>
							 | 
						||
| 
								 | 
							
								struct Times_<SubParser>::Impl<Input, Tuple<>> {
							 | 
						||
| 
								 | 
							
								  // If the sub-parser output is Tuple<>, just return a count.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  static Maybe<Tuple<>> apply(const SubParser& subParser, uint count, Input& input) {
							 | 
						||
| 
								 | 
							
								    uint actualCount = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while (actualCount < count) {
							 | 
						||
| 
								 | 
							
								      if (input.atEnd()) {
							 | 
						||
| 
								 | 
							
								        return nullptr;
							 | 
						||
| 
								 | 
							
								      } else KJ_IF_MAYBE(subResult, subParser(input)) {
							 | 
						||
| 
								 | 
							
								        ++actualCount;
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        return nullptr;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return tuple();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser>
							 | 
						||
| 
								 | 
							
								template <typename Input>
							 | 
						||
| 
								 | 
							
								auto Times_<SubParser>::operator()(Input& input) const
							 | 
						||
| 
								 | 
							
								    -> decltype(Impl<Input>::apply(instance<const SubParser&>(), instance<uint>(), input)) {
							 | 
						||
| 
								 | 
							
								  return Impl<Input, OutputType<SubParser, Input>>::apply(subParser, count, input);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser>
							 | 
						||
| 
								 | 
							
								constexpr Times_<SubParser> times(SubParser&& subParser, uint count) {
							 | 
						||
| 
								 | 
							
								  // Constructs a parser that repeats the subParser exactly `count` times.
							 | 
						||
| 
								 | 
							
								  return Times_<SubParser>(kj::fwd<SubParser>(subParser), count);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// optional()
							 | 
						||
| 
								 | 
							
								// Output = Maybe<output of sub-parser>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser>
							 | 
						||
| 
								 | 
							
								class Optional_ {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  explicit constexpr Optional_(SubParser&& subParser)
							 | 
						||
| 
								 | 
							
								      : subParser(kj::fwd<SubParser>(subParser)) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  Maybe<Maybe<OutputType<SubParser, Input>>> operator()(Input& input) const {
							 | 
						||
| 
								 | 
							
								    typedef Maybe<OutputType<SubParser, Input>> Result;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Input subInput(input);
							 | 
						||
| 
								 | 
							
								    KJ_IF_MAYBE(subResult, subParser(subInput)) {
							 | 
						||
| 
								 | 
							
								      subInput.advanceParent();
							 | 
						||
| 
								 | 
							
								      return Result(kj::mv(*subResult));
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      return Result(nullptr);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								  SubParser subParser;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser>
							 | 
						||
| 
								 | 
							
								constexpr Optional_<SubParser> optional(SubParser&& subParser) {
							 | 
						||
| 
								 | 
							
								  // Constructs a parser that accepts zero or one of the given sub-parser, returning a Maybe
							 | 
						||
| 
								 | 
							
								  // of the sub-parser's result.
							 | 
						||
| 
								 | 
							
								  return Optional_<SubParser>(kj::fwd<SubParser>(subParser));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// oneOf()
							 | 
						||
| 
								 | 
							
								// All SubParsers must have same output type, which becomes the output type of the
							 | 
						||
| 
								 | 
							
								// OneOfParser.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename... SubParsers>
							 | 
						||
| 
								 | 
							
								class OneOf_;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename FirstSubParser, typename... SubParsers>
							 | 
						||
| 
								 | 
							
								class OneOf_<FirstSubParser, SubParsers...> {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  explicit constexpr OneOf_(FirstSubParser&& firstSubParser, SubParsers&&... rest)
							 | 
						||
| 
								 | 
							
								      : first(kj::fwd<FirstSubParser>(firstSubParser)), rest(kj::fwd<SubParsers>(rest)...) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  Maybe<OutputType<FirstSubParser, Input>> operator()(Input& input) const {
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      Input subInput(input);
							 | 
						||
| 
								 | 
							
								      Maybe<OutputType<FirstSubParser, Input>> firstResult = first(subInput);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (firstResult != nullptr) {
							 | 
						||
| 
								 | 
							
								        subInput.advanceParent();
							 | 
						||
| 
								 | 
							
								        return kj::mv(firstResult);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Hoping for some tail recursion here...
							 | 
						||
| 
								 | 
							
								    return rest(input);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								  FirstSubParser first;
							 | 
						||
| 
								 | 
							
								  OneOf_<SubParsers...> rest;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <>
							 | 
						||
| 
								 | 
							
								class OneOf_<> {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  decltype(nullptr) operator()(Input& input) const {
							 | 
						||
| 
								 | 
							
								    return nullptr;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename... SubParsers>
							 | 
						||
| 
								 | 
							
								constexpr OneOf_<SubParsers...> oneOf(SubParsers&&... parsers) {
							 | 
						||
| 
								 | 
							
								  // Constructs a parser that accepts one of a set of options.  The parser behaves as the first
							 | 
						||
| 
								 | 
							
								  // sub-parser in the list which returns successfully.  All of the sub-parsers must return the
							 | 
						||
| 
								 | 
							
								  // same type.
							 | 
						||
| 
								 | 
							
								  return OneOf_<SubParsers...>(kj::fwd<SubParsers>(parsers)...);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// transform()
							 | 
						||
| 
								 | 
							
								// Output = Result of applying transform functor to input value.  If input is a tuple, it is
							 | 
						||
| 
								 | 
							
								// unpacked to form the transformation parameters.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename Position>
							 | 
						||
| 
								 | 
							
								struct Span {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  inline const Position& begin() const { return begin_; }
							 | 
						||
| 
								 | 
							
								  inline const Position& end() const { return end_; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  Span() = default;
							 | 
						||
| 
								 | 
							
								  inline constexpr Span(Position&& begin, Position&& end): begin_(mv(begin)), end_(mv(end)) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								  Position begin_;
							 | 
						||
| 
								 | 
							
								  Position end_;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename Position>
							 | 
						||
| 
								 | 
							
								constexpr Span<Decay<Position>> span(Position&& start, Position&& end) {
							 | 
						||
| 
								 | 
							
								  return Span<Decay<Position>>(kj::fwd<Position>(start), kj::fwd<Position>(end));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser, typename TransformFunc>
							 | 
						||
| 
								 | 
							
								class Transform_ {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  explicit constexpr Transform_(SubParser&& subParser, TransformFunc&& transform)
							 | 
						||
| 
								 | 
							
								      : subParser(kj::fwd<SubParser>(subParser)), transform(kj::fwd<TransformFunc>(transform)) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  Maybe<decltype(kj::apply(instance<TransformFunc&>(),
							 | 
						||
| 
								 | 
							
								                           instance<OutputType<SubParser, Input>&&>()))>
							 | 
						||
| 
								 | 
							
								      operator()(Input& input) const {
							 | 
						||
| 
								 | 
							
								    KJ_IF_MAYBE(subResult, subParser(input)) {
							 | 
						||
| 
								 | 
							
								      return kj::apply(transform, kj::mv(*subResult));
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      return nullptr;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								  SubParser subParser;
							 | 
						||
| 
								 | 
							
								  TransformFunc transform;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser, typename TransformFunc>
							 | 
						||
| 
								 | 
							
								class TransformOrReject_ {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  explicit constexpr TransformOrReject_(SubParser&& subParser, TransformFunc&& transform)
							 | 
						||
| 
								 | 
							
								      : subParser(kj::fwd<SubParser>(subParser)), transform(kj::fwd<TransformFunc>(transform)) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  decltype(kj::apply(instance<TransformFunc&>(), instance<OutputType<SubParser, Input>&&>()))
							 | 
						||
| 
								 | 
							
								      operator()(Input& input) const {
							 | 
						||
| 
								 | 
							
								    KJ_IF_MAYBE(subResult, subParser(input)) {
							 | 
						||
| 
								 | 
							
								      return kj::apply(transform, kj::mv(*subResult));
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      return nullptr;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								  SubParser subParser;
							 | 
						||
| 
								 | 
							
								  TransformFunc transform;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser, typename TransformFunc>
							 | 
						||
| 
								 | 
							
								class TransformWithLocation_ {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  explicit constexpr TransformWithLocation_(SubParser&& subParser, TransformFunc&& transform)
							 | 
						||
| 
								 | 
							
								      : subParser(kj::fwd<SubParser>(subParser)), transform(kj::fwd<TransformFunc>(transform)) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  Maybe<decltype(kj::apply(instance<TransformFunc&>(),
							 | 
						||
| 
								 | 
							
								                           instance<Span<Decay<decltype(instance<Input&>().getPosition())>>>(),
							 | 
						||
| 
								 | 
							
								                           instance<OutputType<SubParser, Input>&&>()))>
							 | 
						||
| 
								 | 
							
								      operator()(Input& input) const {
							 | 
						||
| 
								 | 
							
								    auto start = input.getPosition();
							 | 
						||
| 
								 | 
							
								    KJ_IF_MAYBE(subResult, subParser(input)) {
							 | 
						||
| 
								 | 
							
								      return kj::apply(transform, Span<decltype(start)>(kj::mv(start), input.getPosition()),
							 | 
						||
| 
								 | 
							
								                       kj::mv(*subResult));
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      return nullptr;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								  SubParser subParser;
							 | 
						||
| 
								 | 
							
								  TransformFunc transform;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser, typename TransformFunc>
							 | 
						||
| 
								 | 
							
								constexpr Transform_<SubParser, TransformFunc> transform(
							 | 
						||
| 
								 | 
							
								    SubParser&& subParser, TransformFunc&& functor) {
							 | 
						||
| 
								 | 
							
								  // Constructs a parser which executes some other parser and then transforms the result by invoking
							 | 
						||
| 
								 | 
							
								  // `functor` on it.  Typically `functor` is a lambda.  It is invoked using `kj::apply`,
							 | 
						||
| 
								 | 
							
								  // meaning tuples will be unpacked as arguments.
							 | 
						||
| 
								 | 
							
								  return Transform_<SubParser, TransformFunc>(
							 | 
						||
| 
								 | 
							
								      kj::fwd<SubParser>(subParser), kj::fwd<TransformFunc>(functor));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser, typename TransformFunc>
							 | 
						||
| 
								 | 
							
								constexpr TransformOrReject_<SubParser, TransformFunc> transformOrReject(
							 | 
						||
| 
								 | 
							
								    SubParser&& subParser, TransformFunc&& functor) {
							 | 
						||
| 
								 | 
							
								  // Like `transform()` except that `functor` returns a `Maybe`.  If it returns null, parsing fails,
							 | 
						||
| 
								 | 
							
								  // otherwise the parser's result is the content of the `Maybe`.
							 | 
						||
| 
								 | 
							
								  return TransformOrReject_<SubParser, TransformFunc>(
							 | 
						||
| 
								 | 
							
								      kj::fwd<SubParser>(subParser), kj::fwd<TransformFunc>(functor));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser, typename TransformFunc>
							 | 
						||
| 
								 | 
							
								constexpr TransformWithLocation_<SubParser, TransformFunc> transformWithLocation(
							 | 
						||
| 
								 | 
							
								    SubParser&& subParser, TransformFunc&& functor) {
							 | 
						||
| 
								 | 
							
								  // Like `transform` except that `functor` also takes a `Span` as its first parameter specifying
							 | 
						||
| 
								 | 
							
								  // the location of the parsed content.  The span's position type is whatever the parser input's
							 | 
						||
| 
								 | 
							
								  // getPosition() returns.
							 | 
						||
| 
								 | 
							
								  return TransformWithLocation_<SubParser, TransformFunc>(
							 | 
						||
| 
								 | 
							
								      kj::fwd<SubParser>(subParser), kj::fwd<TransformFunc>(functor));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// notLookingAt()
							 | 
						||
| 
								 | 
							
								// Fails if the given parser succeeds at the current location.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser>
							 | 
						||
| 
								 | 
							
								class NotLookingAt_ {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  explicit constexpr NotLookingAt_(SubParser&& subParser)
							 | 
						||
| 
								 | 
							
								      : subParser(kj::fwd<SubParser>(subParser)) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  Maybe<Tuple<>> operator()(Input& input) const {
							 | 
						||
| 
								 | 
							
								    Input subInput(input);
							 | 
						||
| 
								 | 
							
								    subInput.forgetParent();
							 | 
						||
| 
								 | 
							
								    if (subParser(subInput) == nullptr) {
							 | 
						||
| 
								 | 
							
								      return Tuple<>();
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      return nullptr;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								  SubParser subParser;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename SubParser>
							 | 
						||
| 
								 | 
							
								constexpr NotLookingAt_<SubParser> notLookingAt(SubParser&& subParser) {
							 | 
						||
| 
								 | 
							
								  // Constructs a parser which fails at any position where the given parser succeeds.  Otherwise,
							 | 
						||
| 
								 | 
							
								  // it succeeds without consuming any input and returns an empty tuple.
							 | 
						||
| 
								 | 
							
								  return NotLookingAt_<SubParser>(kj::fwd<SubParser>(subParser));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// endOfInput()
							 | 
						||
| 
								 | 
							
								// Output = Tuple<>, only succeeds if at end-of-input
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class EndOfInput_ {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  template <typename Input>
							 | 
						||
| 
								 | 
							
								  Maybe<Tuple<>> operator()(Input& input) const {
							 | 
						||
| 
								 | 
							
								    if (input.atEnd()) {
							 | 
						||
| 
								 | 
							
								      return Tuple<>();
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      return nullptr;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								constexpr EndOfInput_ endOfInput = EndOfInput_();
							 | 
						||
| 
								 | 
							
								// A parser that succeeds only if it is called with no input.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}  // namespace parse
							 | 
						||
| 
								 | 
							
								}  // namespace kj
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif  // KJ_PARSE_COMMON_H_
							 |