|
|
@@ -3,6 +3,7 @@
|
|
|
#include <charconv>
|
|
|
#include <iostream>
|
|
|
#include <sstream>
|
|
|
+#include <stdexcept>
|
|
|
#include <string>
|
|
|
#include <variant>
|
|
|
|
|
|
@@ -56,13 +57,25 @@ static repeated parse_repeated(std::string & token) {
|
|
|
return rval;
|
|
|
}
|
|
|
|
|
|
+static int base(char c) {
|
|
|
+ using std::string_literals::operator""s;
|
|
|
+ static std::unordered_map<char, int> const s_bases{{'x', 16}, {'d', 10}};
|
|
|
+ auto it = s_bases.find(c);
|
|
|
+ if (it == s_bases.end()) {
|
|
|
+ throw std::invalid_argument("Unknown Base for Character Range: '"s + c +
|
|
|
+ "'");
|
|
|
+ }
|
|
|
+ return it->second;
|
|
|
+}
|
|
|
+
|
|
|
char_range parse_char_range(std::string_view token) {
|
|
|
char_range rval;
|
|
|
+ int const base = abnf::base(token[1]);
|
|
|
token.remove_prefix(2);
|
|
|
char const * const last = token.end();
|
|
|
- auto [end, ec] = std::from_chars(token.data(), last, rval.first.value_, 16);
|
|
|
+ auto [end, ec] = std::from_chars(token.data(), last, rval.first.value_, base);
|
|
|
if (*end == '-') {
|
|
|
- ec = std::from_chars(end + 1, last, rval.last.value_, 16).ec;
|
|
|
+ ec = std::from_chars(end + 1, last, rval.last.value_, base).ec;
|
|
|
} else {
|
|
|
rval.last = rval.first;
|
|
|
}
|
|
|
@@ -90,7 +103,7 @@ static std::string parse_rule(std::istream & in, std::string const & name,
|
|
|
parse_rule(in, name, tmp.rule);
|
|
|
}
|
|
|
append(rule, tmp, is_one_of);
|
|
|
- } else if (token.starts_with("%x")) {
|
|
|
+ } else if (token.starts_with("%")) {
|
|
|
append(rule, parse_char_range(token), is_one_of);
|
|
|
} else if (token.starts_with('"')) {
|
|
|
append(rule, literal{token}, is_one_of);
|