forked from OSchip/llvm-project
[flang] Resolve some TODOs in the grammar.
Original-commit: flang-compiler/f18@6ef9e2388b Reviewed-on: https://github.com/flang-compiler/f18/pull/39
This commit is contained in:
parent
828cff6dbb
commit
382edf056b
|
@ -124,7 +124,7 @@ last (_pace_ the standard C library conventions for `memcpy()` & al.).
|
|||
explicitly, it should contains either a `default:;` at its end or a
|
||||
`default:` label that obviously crashes.
|
||||
#### Classes
|
||||
1. Define only POD structures with `struct`.
|
||||
1. Define POD structures with `struct`.
|
||||
1. Don't use `this->` in (non-static) member functions.
|
||||
1. Define accessor and mutator member functions (implicitly) inline in the
|
||||
class, after constructors and assignments. Don't needlessly define
|
||||
|
|
|
@ -178,13 +178,15 @@ as function calls. The semantic analysis phase of the compiler performs
|
|||
local rewrites of the parse tree once it can be disambiguated by symbols
|
||||
and types.
|
||||
|
||||
Formally speaking, this parser is based on recursive descent with localized
|
||||
backtracking. It is not generated as a table or code from a specification
|
||||
of the Fortran grammar; rather, it _is_ the grammar, as declaratively
|
||||
respecified in C++ constant expressions using a small collection of basic
|
||||
token recognition objects and a library of "parser combinator" template
|
||||
functions that compose them to form more complicated recognizers and
|
||||
their correspondences to the construction of parse tree values.
|
||||
Formally speaking, this parser is based on recursive descent with
|
||||
localized backtracking (specifically, it will not backtrack into a
|
||||
successful reduction to try its other alternatives). It is not generated
|
||||
as a table or code from a specification of the Fortran grammar; rather, it
|
||||
_is_ the grammar, as declaratively respecified in C++ constant expressions
|
||||
using a small collection of basic token recognition objects and a library
|
||||
of "parser combinator" template functions that compose them to form more
|
||||
complicated recognizers and their correspondences to the construction
|
||||
of parse tree values.
|
||||
|
||||
Unparsing
|
||||
---------
|
||||
|
|
|
@ -91,10 +91,10 @@ struct ControlEditDesc {
|
|||
ControlEditDesc(ControlEditDesc &&) = default;
|
||||
ControlEditDesc &operator=(ControlEditDesc &&) = default;
|
||||
explicit ControlEditDesc(Kind k) : kind{k} {}
|
||||
ControlEditDesc(Kind k, int ct) : kind{k}, count{ct} {}
|
||||
ControlEditDesc(int ct, Kind k) : kind{k}, count{ct} {}
|
||||
ControlEditDesc(Kind k, std::int64_t ct) : kind{k}, count{ct} {}
|
||||
ControlEditDesc(std::int64_t ct, Kind k) : kind{k}, count{ct} {}
|
||||
Kind kind;
|
||||
int count{1}; // r, k, or n
|
||||
std::int64_t count{1}; // r, k, or n
|
||||
};
|
||||
|
||||
// R1304 format-item ->
|
||||
|
@ -107,10 +107,10 @@ struct FormatItem {
|
|||
FormatItem(FormatItem &&) = default;
|
||||
FormatItem &operator=(FormatItem &&) = default;
|
||||
template<typename A>
|
||||
FormatItem(std::optional<int> &&r, A &&x)
|
||||
FormatItem(std::optional<std::uint64_t> &&r, A &&x)
|
||||
: repeatCount{std::move(r)}, u{std::move(x)} {}
|
||||
template<typename A> explicit FormatItem(A &&x) : u{std::move(x)} {}
|
||||
std::optional<int> repeatCount;
|
||||
std::optional<std::uint64_t> repeatCount;
|
||||
std::variant<IntrinsicTypeDataEditDesc, DerivedTypeDataEditDesc,
|
||||
ControlEditDesc, std::string, std::list<FormatItem>>
|
||||
u;
|
||||
|
|
|
@ -159,7 +159,7 @@ template<typename PA> inline constexpr auto indirect(const PA &p) {
|
|||
|
||||
// R711 digit-string -> digit [digit]...
|
||||
// N.B. not a token -- no space is skipped
|
||||
constexpr auto digitString = DigitString{};
|
||||
constexpr DigitString digitString;
|
||||
|
||||
// statement(p) parses Statement<P> for some statement type P that is the
|
||||
// result type of the argument parser p, while also handling labels and
|
||||
|
@ -707,17 +707,7 @@ TYPE_PARSER(construct<KindSelector>{}(
|
|||
|
||||
// R710 signed-digit-string -> [sign] digit-string
|
||||
// N.B. Not a complete token -- no space is skipped.
|
||||
static inline std::int64_t negate(std::uint64_t &&n) {
|
||||
return -n; // TODO: check for overflow
|
||||
}
|
||||
|
||||
static inline std::int64_t castToSigned(std::uint64_t &&n) {
|
||||
return n; // TODO: check for overflow
|
||||
}
|
||||
|
||||
constexpr auto signedDigitString = "-"_ch >>
|
||||
applyFunction(negate, digitString) ||
|
||||
maybe("+"_ch) >> applyFunction(castToSigned, digitString);
|
||||
constexpr SignedDigitString signedDigitString;
|
||||
|
||||
// R707 signed-int-literal-constant -> [sign] int-literal-constant
|
||||
TYPE_PARSER(space >> sourced(construct<SignedIntLiteralConstant>{}(
|
||||
|
@ -3081,11 +3071,7 @@ constexpr auto formatItems =
|
|||
nonemptySeparated(space >> Parser<format::FormatItem>{}, maybe(","_tok));
|
||||
|
||||
// R1306 r -> digit-string
|
||||
static inline int castU64ToInt(std::uint64_t &&n) {
|
||||
return n; // TODO: check for overflow
|
||||
}
|
||||
|
||||
constexpr auto repeat = space >> applyFunction(castU64ToInt, digitString);
|
||||
constexpr auto repeat = space >> digitString;
|
||||
|
||||
// R1304 format-item ->
|
||||
// [r] data-edit-desc | control-edit-desc | char-string-edit-desc |
|
||||
|
@ -3177,11 +3163,8 @@ TYPE_PARSER("D"_ch >> "T"_ch >>
|
|||
defaulted(parenthesized(nonemptyList(space >> signedDigitString)))))
|
||||
|
||||
// R1314 k -> [sign] digit-string
|
||||
static inline int castS64ToInt(std::int64_t &&n) {
|
||||
return n; // TODO: check for overflow
|
||||
}
|
||||
constexpr auto scaleFactor = space >>
|
||||
applyFunction(castS64ToInt, signedDigitString);
|
||||
constexpr auto count = space >> DigitStringAsPositive{};
|
||||
constexpr auto scaleFactor = count;
|
||||
|
||||
// R1313 control-edit-desc ->
|
||||
// position-edit-desc | [r] / | : | sign-edit-desc | k P |
|
||||
|
@ -3196,8 +3179,8 @@ TYPE_PARSER(construct<format::ControlEditDesc>{}("T"_ch >>
|
|||
("L"_ch >> pure(format::ControlEditDesc::Kind::TL) ||
|
||||
"R"_ch >> pure(format::ControlEditDesc::Kind::TR) ||
|
||||
pure(format::ControlEditDesc::Kind::T)),
|
||||
repeat) ||
|
||||
construct<format::ControlEditDesc>{}(repeat,
|
||||
count) ||
|
||||
construct<format::ControlEditDesc>{}(count,
|
||||
"X"_ch >> pure(format::ControlEditDesc::Kind::X) ||
|
||||
"/"_ch >> pure(format::ControlEditDesc::Kind::Slash)) ||
|
||||
construct<format::ControlEditDesc>{}(
|
||||
|
|
|
@ -457,6 +457,49 @@ constexpr struct SkipDigitString {
|
|||
}
|
||||
} skipDigitString;
|
||||
|
||||
struct DigitStringAsPositive {
|
||||
using resultType = std::int64_t;
|
||||
static std::optional<std::int64_t> Parse(ParseState *state) {
|
||||
Location at{state->GetLocation()};
|
||||
std::optional<std::uint64_t> x{DigitString{}.Parse(state)};
|
||||
if (!x.has_value()) {
|
||||
return {};
|
||||
}
|
||||
if (*x > std::numeric_limits<std::int64_t>::max()) {
|
||||
state->Say(at, "overflow in positive decimal literal"_err_en_US);
|
||||
}
|
||||
std::int64_t value = *x;
|
||||
return {value};
|
||||
}
|
||||
};
|
||||
|
||||
struct SignedDigitString {
|
||||
using resultType = std::int64_t;
|
||||
static std::optional<std::int64_t> Parse(ParseState *state) {
|
||||
std::optional<const char *> sign{state->PeekAtNextChar()};
|
||||
if (!sign.has_value()) {
|
||||
return {};
|
||||
}
|
||||
bool negate{**sign == '-'};
|
||||
if (negate || **sign == '+') {
|
||||
state->UncheckedAdvance();
|
||||
}
|
||||
std::optional<std::uint64_t> x{DigitString{}.Parse(state)};
|
||||
if (!x.has_value()) {
|
||||
return {};
|
||||
}
|
||||
std::uint64_t limit{std::numeric_limits<std::int64_t>::max()};
|
||||
if (negate) {
|
||||
limit = -(limit + 1);
|
||||
}
|
||||
if (*x > limit) {
|
||||
state->Say(*sign, "overflow in signed decimal literal"_err_en_US);
|
||||
}
|
||||
std::int64_t value = *x;
|
||||
return {negate ? -value : value};
|
||||
}
|
||||
};
|
||||
|
||||
// Legacy feature: Hollerith literal constants
|
||||
struct HollerithLiteral {
|
||||
using resultType = std::string;
|
||||
|
|
Loading…
Reference in New Issue