| // 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 |