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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#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> 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()) { return errors::reject(state, errors::AmbiguousMatch {}); } if (lhs_result.has_success()) { return lhs_result; } if (rhs_result.has_success()) { return rhs_result; } return errors::reject(state, errors::UnexpectedInput {}); } 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 &reject = lhs_result.get_failure(); auto const &error = reject.get_error(); return errors::reject(state, 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 &reject = rhs_result.get_failure(); auto const &error = reject.get_error(); return errors::reject(state, 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 errors::accept(rhs_next_state, std::make_pair(lhs_value, rhs_value)); } template<typename PARSER, typename FUNCTION> Into<PARSER, FUNCTION>::Into(PARSER const &parser, FUNCTION const &function) : my_parser { parser }, my_function { function } { } template<typename PARSER, typename FUNCTION> auto Into<PARSER, FUNCTION>::operator()(StateType const &state) const -> ResultType { auto const lhs_result = my_parser(state); if (lhs_result.has_failure()) { auto const &reject = lhs_result.get_failure(); auto const &error = reject.get_error(); return errors::reject(state, error); } auto const &lhs_accept = lhs_result.get_success(); auto const rhs_parser = my_function(lhs_accept.get_value()); auto const rhs_result = rhs_parser(lhs_accept.get_state()); if (rhs_result.has_failure()) { auto const &reject = rhs_result.get_failure(); auto const &error = reject.get_error(); return errors::reject(state, error); } auto const &rhs_accept = rhs_result.get_success(); return errors::accept(rhs_accept.get_state(), rhs_accept.get_value()); } template<typename PARSER> SequenceOf<PARSER>::SequenceOf(PARSER const &parser, std::size_t const repetitions) : my_parser { parser }, my_repetitions { repetitions } { } template<typename PARSER> auto SequenceOf<PARSER>::operator()(StateType const &state) const -> ResultType { std::vector<ElementType> values {}; StateType next_state { state }; for (std::size_t i { 0 }; i < my_repetitions; ++i) { auto const result { my_parser(next_state) }; if (result.has_failure()) { auto const &reject = result.get_failure(); auto const &error = reject.get_error(); return errors::reject(state, error); } auto const &accept { result.get_success() }; values.emplace_back(accept.get_value()); next_state = accept.get_state(); } return errors::accept(next_state, values); } 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 }; } template<typename PARSER, typename FUNCTION> auto operator>>(PARSER const &parser, FUNCTION const &function) -> Into<PARSER, FUNCTION> { return { parser, function }; } template<typename PARSER> auto operator*(PARSER const &parser, std::size_t const repetitions) -> SequenceOf<PARSER> { return { parser, repetitions }; } } } #endif // CRUCIBLE_PARSING_COMBINATORS_INL