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
|
explicitly, it should contains either a `default:;` at its end or a
|
||||||
`default:` label that obviously crashes.
|
`default:` label that obviously crashes.
|
||||||
#### Classes
|
#### 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. Don't use `this->` in (non-static) member functions.
|
||||||
1. Define accessor and mutator member functions (implicitly) inline in the
|
1. Define accessor and mutator member functions (implicitly) inline in the
|
||||||
class, after constructors and assignments. Don't needlessly define
|
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
|
local rewrites of the parse tree once it can be disambiguated by symbols
|
||||||
and types.
|
and types.
|
||||||
|
|
||||||
Formally speaking, this parser is based on recursive descent with localized
|
Formally speaking, this parser is based on recursive descent with
|
||||||
backtracking. It is not generated as a table or code from a specification
|
localized backtracking (specifically, it will not backtrack into a
|
||||||
of the Fortran grammar; rather, it _is_ the grammar, as declaratively
|
successful reduction to try its other alternatives). It is not generated
|
||||||
respecified in C++ constant expressions using a small collection of basic
|
as a table or code from a specification of the Fortran grammar; rather, it
|
||||||
token recognition objects and a library of "parser combinator" template
|
_is_ the grammar, as declaratively respecified in C++ constant expressions
|
||||||
functions that compose them to form more complicated recognizers and
|
using a small collection of basic token recognition objects and a library
|
||||||
their correspondences to the construction of parse tree values.
|
of "parser combinator" template functions that compose them to form more
|
||||||
|
complicated recognizers and their correspondences to the construction
|
||||||
|
of parse tree values.
|
||||||
|
|
||||||
Unparsing
|
Unparsing
|
||||||
---------
|
---------
|
||||||
|
|
|
@ -91,10 +91,10 @@ struct ControlEditDesc {
|
||||||
ControlEditDesc(ControlEditDesc &&) = default;
|
ControlEditDesc(ControlEditDesc &&) = default;
|
||||||
ControlEditDesc &operator=(ControlEditDesc &&) = default;
|
ControlEditDesc &operator=(ControlEditDesc &&) = default;
|
||||||
explicit ControlEditDesc(Kind k) : kind{k} {}
|
explicit ControlEditDesc(Kind k) : kind{k} {}
|
||||||
ControlEditDesc(Kind k, int ct) : kind{k}, count{ct} {}
|
ControlEditDesc(Kind k, std::int64_t ct) : kind{k}, count{ct} {}
|
||||||
ControlEditDesc(int ct, Kind k) : kind{k}, count{ct} {}
|
ControlEditDesc(std::int64_t ct, Kind k) : kind{k}, count{ct} {}
|
||||||
Kind kind;
|
Kind kind;
|
||||||
int count{1}; // r, k, or n
|
std::int64_t count{1}; // r, k, or n
|
||||||
};
|
};
|
||||||
|
|
||||||
// R1304 format-item ->
|
// R1304 format-item ->
|
||||||
|
@ -107,10 +107,10 @@ struct FormatItem {
|
||||||
FormatItem(FormatItem &&) = default;
|
FormatItem(FormatItem &&) = default;
|
||||||
FormatItem &operator=(FormatItem &&) = default;
|
FormatItem &operator=(FormatItem &&) = default;
|
||||||
template<typename A>
|
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)} {}
|
: repeatCount{std::move(r)}, u{std::move(x)} {}
|
||||||
template<typename A> explicit FormatItem(A &&x) : 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,
|
std::variant<IntrinsicTypeDataEditDesc, DerivedTypeDataEditDesc,
|
||||||
ControlEditDesc, std::string, std::list<FormatItem>>
|
ControlEditDesc, std::string, std::list<FormatItem>>
|
||||||
u;
|
u;
|
||||||
|
|
|
@ -159,7 +159,7 @@ template<typename PA> inline constexpr auto indirect(const PA &p) {
|
||||||
|
|
||||||
// R711 digit-string -> digit [digit]...
|
// R711 digit-string -> digit [digit]...
|
||||||
// N.B. not a token -- no space is skipped
|
// 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
|
// 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
|
// 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
|
// R710 signed-digit-string -> [sign] digit-string
|
||||||
// N.B. Not a complete token -- no space is skipped.
|
// N.B. Not a complete token -- no space is skipped.
|
||||||
static inline std::int64_t negate(std::uint64_t &&n) {
|
constexpr SignedDigitString signedDigitString;
|
||||||
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);
|
|
||||||
|
|
||||||
// R707 signed-int-literal-constant -> [sign] int-literal-constant
|
// R707 signed-int-literal-constant -> [sign] int-literal-constant
|
||||||
TYPE_PARSER(space >> sourced(construct<SignedIntLiteralConstant>{}(
|
TYPE_PARSER(space >> sourced(construct<SignedIntLiteralConstant>{}(
|
||||||
|
@ -3081,11 +3071,7 @@ constexpr auto formatItems =
|
||||||
nonemptySeparated(space >> Parser<format::FormatItem>{}, maybe(","_tok));
|
nonemptySeparated(space >> Parser<format::FormatItem>{}, maybe(","_tok));
|
||||||
|
|
||||||
// R1306 r -> digit-string
|
// R1306 r -> digit-string
|
||||||
static inline int castU64ToInt(std::uint64_t &&n) {
|
constexpr auto repeat = space >> digitString;
|
||||||
return n; // TODO: check for overflow
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr auto repeat = space >> applyFunction(castU64ToInt, digitString);
|
|
||||||
|
|
||||||
// R1304 format-item ->
|
// R1304 format-item ->
|
||||||
// [r] data-edit-desc | control-edit-desc | char-string-edit-desc |
|
// [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)))))
|
defaulted(parenthesized(nonemptyList(space >> signedDigitString)))))
|
||||||
|
|
||||||
// R1314 k -> [sign] digit-string
|
// R1314 k -> [sign] digit-string
|
||||||
static inline int castS64ToInt(std::int64_t &&n) {
|
constexpr auto count = space >> DigitStringAsPositive{};
|
||||||
return n; // TODO: check for overflow
|
constexpr auto scaleFactor = count;
|
||||||
}
|
|
||||||
constexpr auto scaleFactor = space >>
|
|
||||||
applyFunction(castS64ToInt, signedDigitString);
|
|
||||||
|
|
||||||
// R1313 control-edit-desc ->
|
// R1313 control-edit-desc ->
|
||||||
// position-edit-desc | [r] / | : | sign-edit-desc | k P |
|
// 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) ||
|
("L"_ch >> pure(format::ControlEditDesc::Kind::TL) ||
|
||||||
"R"_ch >> pure(format::ControlEditDesc::Kind::TR) ||
|
"R"_ch >> pure(format::ControlEditDesc::Kind::TR) ||
|
||||||
pure(format::ControlEditDesc::Kind::T)),
|
pure(format::ControlEditDesc::Kind::T)),
|
||||||
repeat) ||
|
count) ||
|
||||||
construct<format::ControlEditDesc>{}(repeat,
|
construct<format::ControlEditDesc>{}(count,
|
||||||
"X"_ch >> pure(format::ControlEditDesc::Kind::X) ||
|
"X"_ch >> pure(format::ControlEditDesc::Kind::X) ||
|
||||||
"/"_ch >> pure(format::ControlEditDesc::Kind::Slash)) ||
|
"/"_ch >> pure(format::ControlEditDesc::Kind::Slash)) ||
|
||||||
construct<format::ControlEditDesc>{}(
|
construct<format::ControlEditDesc>{}(
|
||||||
|
|
|
@ -457,6 +457,49 @@ constexpr struct SkipDigitString {
|
||||||
}
|
}
|
||||||
} 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
|
// Legacy feature: Hollerith literal constants
|
||||||
struct HollerithLiteral {
|
struct HollerithLiteral {
|
||||||
using resultType = std::string;
|
using resultType = std::string;
|
||||||
|
|
Loading…
Reference in New Issue