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
flang/lib/parser
|
@ -3,11 +3,12 @@
|
||||||
namespace Fortran {
|
namespace Fortran {
|
||||||
namespace parser {
|
namespace parser {
|
||||||
|
|
||||||
std::string SetOfCharsToString(SetOfChars set) {
|
std::string SetOfChars::ToString() const {
|
||||||
std::string result;
|
std::string result;
|
||||||
|
std::uint64_t set{bits_};
|
||||||
for (char ch{' '}; set != 0; ++ch) {
|
for (char ch{' '}; set != 0; ++ch) {
|
||||||
if (IsCharInSet(set, ch)) {
|
if (IsCharInSet(set, ch)) {
|
||||||
set -= SingletonChar(ch);
|
set -= EncodeChar(ch);
|
||||||
result += ch;
|
result += ch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,18 @@
|
||||||
namespace Fortran {
|
namespace Fortran {
|
||||||
namespace parser {
|
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*/) {
|
if (c <= 32 /*space*/) {
|
||||||
// map control characters, incl. LF (newline), to '?'
|
// map control characters, incl. LF (newline), to '?'
|
||||||
c = '?';
|
c = '?';
|
||||||
|
@ -25,52 +34,25 @@ static constexpr char SixBitEncoding(char c) {
|
||||||
// map lower-case letters to upper-case
|
// map lower-case letters to upper-case
|
||||||
c -= 32;
|
c -= 32;
|
||||||
}
|
}
|
||||||
// range is now [32..95]; reduce to [0..63]
|
// range is now [32..95]; reduce to [0..63] and use as a shift count
|
||||||
return c - 32;
|
return static_cast<std::uint64_t>(1) << (c - 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr char SixBitDecoding(char c) {
|
static constexpr SetOfChars SingletonChar(char c) { return {EncodeChar(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 CharsToSet(const char str[], std::size_t n = 256) {
|
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) {
|
for (std::size_t j{0}; j < n; ++j) {
|
||||||
if (str[j] == '\0') {
|
if (str[j] == '\0') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
chars |= SingletonChar(str[j]);
|
chars.bits_ |= EncodeChar(str[j]);
|
||||||
}
|
}
|
||||||
return chars;
|
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) {
|
static inline constexpr bool IsCharInSet(SetOfChars set, char c) {
|
||||||
return (set & SingletonChar(c)) != 0;
|
return (set.bits_ & EncodeChar(c)) != 0;
|
||||||
}
|
|
||||||
|
|
||||||
static inline constexpr bool IsSingleton(SetOfChars set) {
|
|
||||||
return (set & (set - 1)) == emptySetOfChars;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SetOfCharsToString(SetOfChars);
|
std::string SetOfCharsToString(SetOfChars);
|
||||||
|
|
|
@ -39,8 +39,8 @@ MessageFormattedText::MessageFormattedText(MessageFixedText text, ...)
|
||||||
void Message::Incorporate(Message &that) {
|
void Message::Incorporate(Message &that) {
|
||||||
if (provenance_ == that.provenance_ &&
|
if (provenance_ == that.provenance_ &&
|
||||||
cookedSourceLocation_ == that.cookedSourceLocation_ &&
|
cookedSourceLocation_ == that.cookedSourceLocation_ &&
|
||||||
expected_ != emptySetOfChars) {
|
expected_.bits_ != 0) {
|
||||||
expected_ |= that.expected_;
|
expected_.bits_ |= that.expected_.bits_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,12 +58,12 @@ std::string Message::ToString() const {
|
||||||
} else {
|
} else {
|
||||||
SetOfChars expect{expected_};
|
SetOfChars expect{expected_};
|
||||||
if (IsCharInSet(expect, '\n')) {
|
if (IsCharInSet(expect, '\n')) {
|
||||||
expect -= SingletonChar('\n');
|
expect.bits_ &= ~SingletonChar('\n').bits_;
|
||||||
if (expect == emptySetOfChars) {
|
if (expect.bits_ == 0) {
|
||||||
return "expected end of line"_err_en_US.ToString();
|
return "expected end of line"_err_en_US.ToString();
|
||||||
} else {
|
} else {
|
||||||
s = SetOfCharsToString(expect);
|
s = expect.ToString();
|
||||||
if (IsSingleton(expect)) {
|
if (s.size() == 1) {
|
||||||
return MessageFormattedText(
|
return MessageFormattedText(
|
||||||
"expected end of line or '%s'"_err_en_US, s.data())
|
"expected end of line or '%s'"_err_en_US, s.data())
|
||||||
.MoveString();
|
.MoveString();
|
||||||
|
@ -74,8 +74,8 @@ std::string Message::ToString() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s = SetOfCharsToString(expect);
|
s = expect.ToString();
|
||||||
if (!IsSingleton(expect)) {
|
if (s.size() != 1) {
|
||||||
return MessageFormattedText("expected one of '%s'"_err_en_US, s.data())
|
return MessageFormattedText("expected one of '%s'"_err_en_US, s.data())
|
||||||
.MoveString();
|
.MoveString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ public:
|
||||||
private:
|
private:
|
||||||
const char *str_{nullptr};
|
const char *str_{nullptr};
|
||||||
std::size_t bytes_{0};
|
std::size_t bytes_{0};
|
||||||
SetOfChars set_{emptySetOfChars};
|
SetOfChars set_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Message : public ReferenceCounted<Message> {
|
class Message : public ReferenceCounted<Message> {
|
||||||
|
@ -149,7 +149,7 @@ private:
|
||||||
std::size_t fixedBytes_{0};
|
std::size_t fixedBytes_{0};
|
||||||
bool isExpected_{false};
|
bool isExpected_{false};
|
||||||
std::string string_;
|
std::string string_;
|
||||||
SetOfChars expected_{emptySetOfChars};
|
SetOfChars expected_;
|
||||||
Context context_;
|
Context context_;
|
||||||
bool isFatal_{false};
|
bool isFatal_{false};
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SetOfChars set_;
|
const SetOfChars set_;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr AnyOfChars operator""_ch(const char str[], std::size_t n) {
|
constexpr AnyOfChars operator""_ch(const char str[], std::size_t n) {
|
||||||
|
|
Loading…
Reference in New Issue