|
|
@@ -25,28 +25,34 @@ static void append(rule & rule, rule_part const & part, bool is_one_of) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static repeated parse_repeated(std::string_view token) {
|
|
|
- if (token[0] == '[') { return {.min = 0, .max = 1}; }
|
|
|
+static repeated parse_repeated(std::string & token) {
|
|
|
+ if (token[0] == '[') {
|
|
|
+ token.erase(0, 1);
|
|
|
+ return {.min = 0, .max = 1};
|
|
|
+ }
|
|
|
if (token[0] == '(') {
|
|
|
// TODO: Can I just inline this when is_one_of is false?
|
|
|
+ token.erase(0, 1);
|
|
|
return {.min = 1, .max = 1};
|
|
|
}
|
|
|
repeated rval;
|
|
|
size_t idx = 0;
|
|
|
if (not token.starts_with('*')) {
|
|
|
- rval.min = std::stoull(std::string(token), &idx);
|
|
|
- token.remove_prefix(idx);
|
|
|
+ rval.min = std::stoull(token, &idx);
|
|
|
+ token.erase(0, idx);
|
|
|
}
|
|
|
if (not token.starts_with('*')) {
|
|
|
+ token.erase(0, token[0] == '(' ? 1 : 0);
|
|
|
rval.max = rval.min;
|
|
|
return rval;
|
|
|
}
|
|
|
|
|
|
- token.remove_prefix(1);
|
|
|
+ token.erase(0, 1);
|
|
|
if (not token.empty() && std::strchr("123456789", token[0])) {
|
|
|
- rval.max = std::stoull(std::string(token), &idx);
|
|
|
- token.remove_prefix(idx);
|
|
|
+ rval.max = std::stoull(token, &idx);
|
|
|
+ token.erase(0, idx);
|
|
|
}
|
|
|
+ token.erase(0, token[0] == '(' ? 1 : 0);
|
|
|
return rval;
|
|
|
}
|
|
|
|
|
|
@@ -77,9 +83,8 @@ static std::string parse_rule(std::istream & in, std::string const & name,
|
|
|
static constexpr char const s_repeated_chars[] = "0123456789[(*";
|
|
|
if (std::strchr(s_repeated_chars, token[0])) {
|
|
|
repeated tmp = parse_repeated(token);
|
|
|
- if (auto pos = token.find_first_not_of(s_repeated_chars);
|
|
|
- pos != std::string::npos) {
|
|
|
- std::stringstream ss(token.substr(pos));
|
|
|
+ if (not token.empty()) {
|
|
|
+ std::stringstream ss(token);
|
|
|
parse_rule(ss, name, tmp.rule);
|
|
|
} else {
|
|
|
parse_rule(in, name, tmp.rule);
|