[flang] Add char-parsers.h.
Original-commit: flang-compiler/f18@0f72c5cb40
This commit is contained in:
114
flang/char-parsers.h
Normal file
114
flang/char-parsers.h
Normal file
@@ -0,0 +1,114 @@
|
||||
#ifndef FORTRAN_CHAR_PARSERS_H_
|
||||
#define FORTRAN_CHAR_PARSERS_H_
|
||||
|
||||
// Defines simple character-level parsers for use by the tokenizing
|
||||
// parsers in cooked-chars.h.
|
||||
|
||||
#include "basic-parsers.h"
|
||||
#include "parse-state.h"
|
||||
#include <optional>
|
||||
|
||||
namespace Fortran {
|
||||
|
||||
template<char goal>
|
||||
struct ExactRaw {
|
||||
using resultType = char;
|
||||
constexpr ExactRaw() {}
|
||||
constexpr ExactRaw(const ExactRaw &) {}
|
||||
static std::optional<char> Parse(ParseState *state) {
|
||||
if (std::optional<char> ch{state->GetNextRawChar()}) {
|
||||
if (*ch == goal) {
|
||||
state->Advance();
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
template<char a, char z>
|
||||
struct ExactRawRange {
|
||||
using resultType = char;
|
||||
constexpr ExactRawRange() {}
|
||||
constexpr ExactRawRange(const ExactRawRange &) {};
|
||||
static std::optional<char> Parse(ParseState *state) {
|
||||
if (std::optional<char> ch{state->GetNextRawChar()}) {
|
||||
if (*ch >= a && *ch <= z) {
|
||||
state->Advance();
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
template<char unwanted>
|
||||
struct AnyCharExcept {
|
||||
using resultType = char;
|
||||
constexpr AnyCharExcept() {}
|
||||
constexpr AnyCharExcept(const AnyCharExcept &) {}
|
||||
static std::optional<char> Parse(ParseState *state) {
|
||||
if (std::optional<char> ch{state->GetNextRawChar()}) {
|
||||
if (*ch != unwanted) {
|
||||
state->Advance();
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
template<char goal>
|
||||
struct SkipPast {
|
||||
using resultType = Success;
|
||||
constexpr SkipPast() {}
|
||||
constexpr SkipPast(const SkipPast &) {}
|
||||
static std::optional<Success> Parse(ParseState *state) {
|
||||
while (std::optional<char> ch{state->GetNextRawChar()}) {
|
||||
state->Advance();
|
||||
if (*ch == goal) {
|
||||
return {Success{}};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
// Line endings have been previously normalized to simple newlines.
|
||||
constexpr auto eoln = ExactRaw<'\n'>{};
|
||||
|
||||
static inline bool InCharLiteral(const ParseState &state) {
|
||||
return state.inCharLiteral();
|
||||
}
|
||||
|
||||
constexpr StatePredicateGuardParser inCharLiteral{InCharLiteral};
|
||||
|
||||
class RawStringMatch {
|
||||
public:
|
||||
using resultType = Success;
|
||||
constexpr RawStringMatch(const RawStringMatch &) = default;
|
||||
constexpr RawStringMatch(const char *str, size_t n) : str_{str}, length_{n} {}
|
||||
std::optional<Success> Parse(ParseState *state) const {
|
||||
const char *p{str_};
|
||||
for (size_t j{0}; j < length_ && *p != '\0'; ++j, ++p) {
|
||||
if (std::optional<char> ch{state->GetNextRawChar()}) {
|
||||
if (tolower(*ch) != *p) {
|
||||
return {};
|
||||
}
|
||||
state->Advance();
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return {Success{}};
|
||||
}
|
||||
private:
|
||||
const char *const str_;
|
||||
const size_t length_;
|
||||
};
|
||||
|
||||
constexpr RawStringMatch operator""_raw(const char str[], size_t n) {
|
||||
return RawStringMatch{str, n};
|
||||
}
|
||||
} // namespace Fortran
|
||||
#endif // FORTRAN_CHAR_PARSERS_H_
|
||||
Reference in New Issue
Block a user