Echo Writes Code

combinators.inl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#ifndef CRUCIBLE_PARSING_COMBINATORS_INL
#define CRUCIBLE_PARSING_COMBINATORS_INL

#include "crucible/parsing/combinators.hpp"

#include "crucible/parsing/outcomes.inl"

namespace crucible::parsing::combinators {
  template<typename LHS_PARSER, typename RHS_PARSER>
  OneOf<LHS_PARSER, RHS_PARSER>::OneOf(LHS_PARSER const &lhs_parser, RHS_PARSER const &rhs_parser) :
    my_lhs_parser(lhs_parser),
    my_rhs_parser(rhs_parser) {
  }

  template<typename LHS_PARSER, typename RHS_PARSER>
  auto OneOf<LHS_PARSER, RHS_PARSER>::operator()(StateType const &state) const -> ParseResult<StateType, ValueType> {
    auto const lhs_result = my_lhs_parser(state);
    auto const rhs_result = my_rhs_parser(state);

    if (lhs_result.has_success() && rhs_result.has_success()) {
      return outcomes::reject(state, ParseError { AmbiguousMatch {} });
    } else if (lhs_result.has_success()) {
      return lhs_result;
    } else if (rhs_result.has_success()) {
      return rhs_result;
    } else {
      return outcomes::reject(state, ParseError { NeitherMatch {} });
    }
  }

  namespace operators {
    template<typename LHS_PARSER, typename RHS_PARSER>
    auto operator^(LHS_PARSER const &lhs_parser, RHS_PARSER const &rhs_parser) -> OneOf<LHS_PARSER, RHS_PARSER> {
      return OneOf { lhs_parser, rhs_parser };
    }
  }
}

#endif // CRUCIBLE_PARSING_COMBINATORS_INL