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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#ifndef CRUCIBLE_PARSING_COMBINATORS_INL #define CRUCIBLE_PARSING_COMBINATORS_INL #include "crucible/parsing/combinators.hpp" #include "crucible/parsing/result.inl" #include <sstream> namespace crucible::parsing::combinators { template<typename LHS_PARSER, typename RHS_PARSER> BothMatch<LHS_PARSER, RHS_PARSER>::BothMatch(StateType const &initial_state, StateType const &lhs_next_state, StateType const &rhs_next_state) : my_initial_state(initial_state), my_lhs_next_state(lhs_next_state), my_rhs_next_state(rhs_next_state) { } template<typename LHS_PARSER, typename RHS_PARSER> auto BothMatch<LHS_PARSER, RHS_PARSER>::format() const -> std::string { std::ostringstream buffer; buffer << "Range of first match: [" << my_initial_state.format_location() << ", " << my_lhs_next_state.format_location() << "]; Range of second match: [" << my_initial_state.format_location() << ", " << my_rhs_next_state.format_location() << "]"; return buffer.str(); } template<typename LHS_PARSER, typename RHS_PARSER> NeitherMatch<LHS_PARSER, RHS_PARSER>::NeitherMatch(LHSError const &lhs_error, RHSError const &rhs_error) : my_lhs_error(lhs_error), my_rhs_error(rhs_error) { } template<typename LHS_PARSER, typename RHS_PARSER> auto NeitherMatch<LHS_PARSER, RHS_PARSER>::format() const -> std::string { std::ostringstream buffer; buffer << "First rejection: '" << my_lhs_error.format() << "'; Second rejection: '" << my_rhs_error.format() << "'"; return buffer.str(); } 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 -> ResultType { 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()) { auto const &lhs_accept = lhs_result.get_success(); auto const &lhs_next_state = lhs_accept.get_state(); auto const &rhs_accept = rhs_result.get_success(); auto const &rhs_next_state = rhs_accept.get_state(); return result::reject(state, OneOfError<LHS_PARSER, RHS_PARSER> { BothMatch<LHS_PARSER, RHS_PARSER> { state, lhs_next_state, rhs_next_state } }); } else if (lhs_result.has_success()) { return lhs_result; } else if (rhs_result.has_success()) { return rhs_result; } else { auto const &lhs_reject = lhs_result.get_failure(); auto const &lhs_error = lhs_reject.get_error(); auto const &rhs_reject = rhs_result.get_failure(); auto const &rhs_error = rhs_reject.get_error(); return result::reject(state, OneOfError<LHS_PARSER, RHS_PARSER> { NeitherMatch<LHS_PARSER, RHS_PARSER> { lhs_error, rhs_error } }); } } template<typename LHS_PARSER, typename RHS_PARSER> AndThen<LHS_PARSER, RHS_PARSER>::AndThen(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 AndThen<LHS_PARSER, RHS_PARSER>::operator()(StateType const &state) const -> ResultType { auto const lhs_result = my_lhs_parser(state); if (lhs_result.has_failure()) { auto const &lhs_reject = lhs_result.get_failure(); auto const &lhs_error = lhs_reject.get_error(); return result::reject(state, lhs_error); } auto const &lhs_accept = lhs_result.get_success(); auto const &lhs_next_state = lhs_accept.get_state(); auto const rhs_result = my_rhs_parser(lhs_next_state); if (rhs_result.has_failure()) { auto const &rhs_reject = rhs_result.get_failure(); auto const &rhs_error = rhs_reject.get_error(); return result::reject(state, rhs_error); } auto const &rhs_accept = rhs_result.get_success(); auto const &rhs_next_state = rhs_accept.get_state(); auto const &lhs_value = lhs_accept.get_value(); auto const &rhs_value = rhs_accept.get_value(); return result::accept(rhs_next_state, std::make_pair(lhs_value, rhs_value)); } 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 { lhs_parser, rhs_parser }; } template<typename LHS_PARSER, typename RHS_PARSER> auto operator&(LHS_PARSER const &lhs_parser, RHS_PARSER const &rhs_parser) -> AndThen<LHS_PARSER, RHS_PARSER> { return { lhs_parser, rhs_parser }; } } } #endif // CRUCIBLE_PARSING_COMBINATORS_INL