blob: cd72081693c44ac18689b93388d4af27024aa118 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/shell/parser/text_match.h"
namespace shell::parser {
namespace {
// Produce a parser which parses any single character from the given list. If invert is true,
// character must NOT be in the list instead.
fit::function<ParseResult(ParseResult)> AnyCharMayInvert(std::string_view chars, bool invert) {
return [chars, invert](ParseResult prefix) {
if (prefix.tail().size() > 0 && (chars.find(prefix.tail()[0]) == std::string::npos) == invert) {
return prefix.Advance(1);
}
return ParseResult::kEnd;
};
}
// Return whether a given character would match a regex-style char group.
bool MatchCharGroup(std::string_view chars, char c) {
size_t pos = 0;
while (pos < chars.size()) {
if (c == chars[pos]) {
return true;
} else if (pos + 2 < chars.size() && chars[pos + 1] == '-') {
if (c > chars[pos] && c <= chars[pos + 2]) {
return true;
}
pos += 3;
} else {
pos += 1;
}
}
return false;
}
} // namespace
fit::function<ParseResult(ParseResult)> AnyChar(std::string_view chars) {
return AnyCharMayInvert(chars, false);
}
ParseResult AnyChar(ParseResult prefix) { return AnyCharBut("")(std::move(prefix)); }
fit::function<ParseResult(ParseResult)> AnyCharBut(std::string_view chars) {
return AnyCharMayInvert(chars, true);
}
fit::function<ParseResult(ParseResult)> CharGroup(std::string_view chars) {
return [chars](ParseResult prefix) {
if (prefix.tail().size() > 0 && MatchCharGroup(chars, prefix.tail()[0])) {
return prefix.Advance(1);
}
return ParseResult::kEnd;
};
}
} // namespace shell::parser