Ver Fonte

fix: allow for use of %d in char-range

Sam Jaffe há 3 meses atrás
pai
commit
ee216b558b
1 ficheiros alterados com 16 adições e 3 exclusões
  1. 16 3
      src/parser.cxx

+ 16 - 3
src/parser.cxx

@@ -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);