-
Notifications
You must be signed in to change notification settings - Fork 2
/
parsing.cxx
68 lines (54 loc) · 1.59 KB
/
parsing.cxx
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
// Boost Licensed
//
module;
#include <cstdint>
#include <string>
export module maud_:parsing;
template <bool INVERT, char... CHARS>
struct CharPredicate {
constexpr bool operator()(char c) const {
bool match = ((c == CHARS) or ...);
return INVERT ? not match : match;
}
constexpr auto operator not() const { return CharPredicate<not INVERT, CHARS...>{}; }
};
export template <char... L, char... R>
constexpr auto operator or(CharPredicate<false, L...> l, CharPredicate<false, R...> r) {
return CharPredicate<false, L..., R...>{};
}
export template <char... CHARS>
constexpr CharPredicate<false, CHARS...> OF{};
export constexpr auto SPACE = OF<' ', '\r', '\n', '\t'>;
export constexpr auto find_first(auto predicate, auto str) {
while (*str != 0 and not predicate(*str)) {
++str;
}
return str;
}
export struct Location {
Location(char const *begin) : line_begin{begin} {}
char const *line_begin;
uint16_t line = 0, column = 0;
char const &operator*() const { return line_begin[column]; }
Location operator++(int) {
Location copy = *this;
++*this;
return copy;
}
Location &operator++() {
if (line_begin[column++] == '\n') {
line_begin += column;
column = 0;
++line;
}
return *this;
}
std::string_view view_line() const {
return {line_begin, find_first(OF<'\r', '\n'>, &**this)};
}
std::string_view view_to(Location end) const { return {&**this, &*end}; }
std::string line_column() const {
return std::to_string(line + 1) + ":" + std::to_string(column + 1);
}
bool operator==(Location const &) const = default;
};