forked from cursey/regenny
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUtility.cpp
47 lines (38 loc) · 1.42 KB
/
Utility.cpp
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
#include <tao/pegtl.hpp>
#include "Utility.hpp"
namespace address_parser {
using namespace tao::pegtl;
struct HexNum : seq<one<'0'>, one<'x'>, plus<xdigit>> {};
struct DecNum : plus<digit> {};
struct Num : sor<HexNum, DecNum> {};
struct NameChar : sor<alnum, one<' ', '(', ')', '_', '-', ',', '.', '/', '\\', ':'>> {};
struct Name : seq<plus<NameChar>> {};
struct Offset : seq<Num, opt<one<'-'>, one<'>'>, struct Offset>> {};
struct ModOffset : seq<one<'<'>, Name, one<'>'>, opt<one<'+'>, Offset>> {};
struct Grammar : sor<Offset, ModOffset> {};
template <typename Rule> struct Action : nothing<Rule> {};
template <> struct Action<Num> {
template <typename Input> static void apply(const Input& in, ParsedAddress& s) {
try {
auto num = std::stoull(in.string(), nullptr, 0);
s.offsets.push_back(num);
} catch (...) {
// Failed to convert.
}
}
};
template <> struct Action<Name> {
template <typename Input> static void apply(const Input& in, ParsedAddress& s) { s.name = in.string_view(); }
};
} // namespace address_parser
std::optional<ParsedAddress> parse_address(const std::string& str) {
try {
ParsedAddress s{};
tao::pegtl::memory_input in{str, ""};
if (tao::pegtl::parse<address_parser::Grammar, address_parser::Action>(in, s)) {
return s;
}
} catch (const tao::pegtl::parse_error& e) {
}
return std::nullopt;
}