forked from OSchip/llvm-project
[flang] repackage SetOfChars as a class type
Original-commit: flang-compiler/f18@bae9199f62 Reviewed-on: https://github.com/flang-compiler/f18/pull/61 Tree-same-pre-rewrite: false
This commit is contained in:
parent
075fe789da
commit
376d8f96d4
|
@ -3,11 +3,12 @@
|
|||
namespace Fortran {
|
||||
namespace parser {
|
||||
|
||||
std::string SetOfCharsToString(SetOfChars set) {
|
||||
std::string SetOfChars::ToString() const {
|
||||
std::string result;
|
||||
std::uint64_t set{bits_};
|
||||
for (char ch{' '}; set != 0; ++ch) {
|
||||
if (IsCharInSet(set, ch)) {
|
||||
set -= SingletonChar(ch);
|
||||
set -= EncodeChar(ch);
|
||||
result += ch;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,18 @@
|
|||
namespace Fortran {
|
||||
namespace parser {
|
||||
|
||||
using SetOfChars = std::uint64_t;
|
||||
struct SetOfChars {
|
||||
constexpr SetOfChars() {}
|
||||
constexpr SetOfChars(std::uint64_t b) : bits_{b} {}
|
||||
constexpr SetOfChars(const SetOfChars &) = default;
|
||||
constexpr SetOfChars(SetOfChars &&) = default;
|
||||
constexpr SetOfChars &operator=(const SetOfChars &) = default;
|
||||
constexpr SetOfChars &operator=(SetOfChars &&) = default;
|
||||
std::string ToString() const;
|
||||
std::uint64_t bits_{0};
|
||||
};
|
||||
|
||||
static constexpr char SixBitEncoding(char c) {
|
||||
static constexpr std::uint64_t EncodeChar(char c) {
|
||||
if (c <= 32 /*space*/) {
|
||||
// map control characters, incl. LF (newline), to '?'
|
||||
c = '?';
|
||||
|
@ -25,52 +34,25 @@ static constexpr char SixBitEncoding(char c) {
|
|||
// map lower-case letters to upper-case
|
||||
c -= 32;
|
||||
}
|
||||
// range is now [32..95]; reduce to [0..63]
|
||||
return 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 char SixBitDecoding(char c) {
|
||||
c += 32;
|
||||
if (c == '?') {
|
||||
return '\n';
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static constexpr SetOfChars SingletonChar(char c) {
|
||||
return static_cast<SetOfChars>(1) << SixBitEncoding(c);
|
||||
}
|
||||
static constexpr SetOfChars SingletonChar(char c) { return {EncodeChar(c)}; }
|
||||
|
||||
static constexpr SetOfChars CharsToSet(const char str[], std::size_t n = 256) {
|
||||
SetOfChars chars{0};
|
||||
SetOfChars chars;
|
||||
for (std::size_t j{0}; j < n; ++j) {
|
||||
if (str[j] == '\0') {
|
||||
break;
|
||||
}
|
||||
chars |= SingletonChar(str[j]);
|
||||
chars.bits_ |= EncodeChar(str[j]);
|
||||
}
|
||||
return chars;
|
||||
}
|
||||
|
||||
static const SetOfChars emptySetOfChars{0};
|
||||
static const SetOfChars fullSetOfChars{~static_cast<SetOfChars>(0)};
|
||||
static const SetOfChars setOfLetters{
|
||||
CharsToSet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")};
|
||||
static const SetOfChars setOfDecimalDigits{CharsToSet("0123456789")};
|
||||
static const SetOfChars setOfIdentifierStarts{setOfLetters | CharsToSet("_@$")};
|
||||
static const SetOfChars setOfIdentifierChars{
|
||||
setOfIdentifierStarts | setOfDecimalDigits};
|
||||
|
||||
// sanity check
|
||||
static_assert(setOfLetters == 0x7fffffe00000000);
|
||||
static_assert(setOfDecimalDigits == 0x3ff0000);
|
||||
|
||||
static inline constexpr bool IsCharInSet(SetOfChars set, char c) {
|
||||
return (set & SingletonChar(c)) != 0;
|
||||
}
|
||||
|
||||
static inline constexpr bool IsSingleton(SetOfChars set) {
|
||||
return (set & (set - 1)) == emptySetOfChars;
|
||||
return (set.bits_ & EncodeChar(c)) != 0;
|
||||
}
|
||||
|
||||
std::string SetOfCharsToString(SetOfChars);
|
||||
|
|
|
@ -39,8 +39,8 @@ MessageFormattedText::MessageFormattedText(MessageFixedText text, ...)
|
|||
void Message::Incorporate(Message &that) {
|
||||
if (provenance_ == that.provenance_ &&
|
||||
cookedSourceLocation_ == that.cookedSourceLocation_ &&
|
||||
expected_ != emptySetOfChars) {
|
||||
expected_ |= that.expected_;
|
||||
expected_.bits_ != 0) {
|
||||
expected_.bits_ |= that.expected_.bits_;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,12 +58,12 @@ std::string Message::ToString() const {
|
|||
} else {
|
||||
SetOfChars expect{expected_};
|
||||
if (IsCharInSet(expect, '\n')) {
|
||||
expect -= SingletonChar('\n');
|
||||
if (expect == emptySetOfChars) {
|
||||
expect.bits_ &= ~SingletonChar('\n').bits_;
|
||||
if (expect.bits_ == 0) {
|
||||
return "expected end of line"_err_en_US.ToString();
|
||||
} else {
|
||||
s = SetOfCharsToString(expect);
|
||||
if (IsSingleton(expect)) {
|
||||
s = expect.ToString();
|
||||
if (s.size() == 1) {
|
||||
return MessageFormattedText(
|
||||
"expected end of line or '%s'"_err_en_US, s.data())
|
||||
.MoveString();
|
||||
|
@ -74,8 +74,8 @@ std::string Message::ToString() const {
|
|||
}
|
||||
}
|
||||
}
|
||||
s = SetOfCharsToString(expect);
|
||||
if (!IsSingleton(expect)) {
|
||||
s = expect.ToString();
|
||||
if (s.size() != 1) {
|
||||
return MessageFormattedText("expected one of '%s'"_err_en_US, s.data())
|
||||
.MoveString();
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ public:
|
|||
private:
|
||||
const char *str_{nullptr};
|
||||
std::size_t bytes_{0};
|
||||
SetOfChars set_{emptySetOfChars};
|
||||
SetOfChars set_;
|
||||
};
|
||||
|
||||
class Message : public ReferenceCounted<Message> {
|
||||
|
@ -149,7 +149,7 @@ private:
|
|||
std::size_t fixedBytes_{0};
|
||||
bool isExpected_{false};
|
||||
std::string string_;
|
||||
SetOfChars expected_{emptySetOfChars};
|
||||
SetOfChars expected_;
|
||||
Context context_;
|
||||
bool isFatal_{false};
|
||||
};
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
SetOfChars set_;
|
||||
const SetOfChars set_;
|
||||
};
|
||||
|
||||
constexpr AnyOfChars operator""_ch(const char str[], std::size_t n) {
|
||||
|
|
Loading…
Reference in New Issue