struct SetOfChars {
constexpr SetOfChars() {}
+ constexpr SetOfChars(char c) {
+ if (c <= 32 /*space*/) {
+ // map control characters, incl. LF (newline), to '?'
+ c = '?';
+ } else if (c >= 127) {
+ // map DEL and 8-bit characters to '^'
+ c = '^';
+ } else if (c >= 96) {
+ // map lower-case letters to upper-case
+ c -= 32;
+ }
+ // range is now [32..95]; reduce to [0..63] and use as a shift count
+ bits_ = static_cast<std::uint64_t>(1) << (c - 32);
+ }
+ constexpr SetOfChars(const char str[], std::size_t n = 256) {
+ for (std::size_t j{0}; j < n; ++j) {
+ bits_ |= SetOfChars{str[j]}.bits_;
+ }
+ }
constexpr SetOfChars(std::uint64_t b) : bits_{b} {}
constexpr SetOfChars(const SetOfChars &) = default;
constexpr SetOfChars(SetOfChars &&) = default;
std::uint64_t bits_{0};
};
-static constexpr std::uint64_t EncodeChar(char c) {
- if (c <= 32 /*space*/) {
- // map control characters, incl. LF (newline), to '?'
- c = '?';
- } else if (c >= 127) {
- // map DEL and 8-bit characters to '^'
- c = '^';
- } else if (c >= 96) {
- // map lower-case letters to upper-case
- c -= 32;
- }
- // range is now [32..95]; reduce to [0..63] and use as a shift count
- return static_cast<std::uint64_t>(1) << (c - 32);
-}
-
-static constexpr SetOfChars SingletonChar(char c) { return {EncodeChar(c)}; }
-
-static constexpr SetOfChars CharsToSet(const char str[], std::size_t n = 256) {
- SetOfChars chars;
- for (std::size_t j{0}; j < n; ++j) {
- if (str[j] == '\0') {
- break;
- }
- chars.bits_ |= EncodeChar(str[j]);
- }
- return chars;
-}
-
static inline constexpr bool IsCharInSet(SetOfChars set, char c) {
- return (set.bits_ & EncodeChar(c)) != 0;
+ return (set.bits_ & SetOfChars{c}.bits_) != 0;
}
-
-std::string SetOfCharsToString(SetOfChars);
} // namespace parser
} // namespace Fortran
#endif // FORTRAN_PARSER_CHAR_SET_H_
};
constexpr AnyOfChars operator""_ch(const char str[], std::size_t n) {
- return AnyOfChars{CharsToSet(str, n)};
+ return AnyOfChars{SetOfChars(str, n)};
}
constexpr auto letter = "abcdefghijklmnopqrstuvwxyz"_ch;
static constexpr auto nextch = attempt(CharLiteralChar{});
while (std::optional<CharLiteralChar::Result> ch{nextch.Parse(state)}) {
if (ch->ch == quote && !ch->wasEscaped) {
- static constexpr auto doubled =
- attempt(AnyOfChars{SingletonChar(quote)});
+ static constexpr auto doubled = attempt(AnyOfChars{SetOfChars{quote}});
if (!doubled.Parse(state).has_value()) {
return {str};
}