From 10907c73db7e5073d435eccf6e38f87b7e814380 Mon Sep 17 00:00:00 2001 From: peter klausler Date: Mon, 2 Apr 2018 16:33:10 -0700 Subject: [PATCH] [flang] Debugging and a TODO. Original-commit: flang-compiler/f18@4fab40bc37e870e3b4fa039d51d7cc8b672f2f36 Reviewed-on: https://github.com/flang-compiler/f18/pull/38 Tree-same-pre-rewrite: false --- flang/lib/parser/basic-parsers.h | 10 ++++----- flang/lib/parser/grammar.h | 8 ++++---- flang/lib/parser/message.h | 1 + flang/lib/parser/parse-state.h | 10 ++++----- flang/lib/parser/parsing.cc | 4 ++-- flang/lib/parser/token-parsers.h | 44 +++++++++++++++++++++++++++++----------- 6 files changed, 48 insertions(+), 29 deletions(-) diff --git a/flang/lib/parser/basic-parsers.h b/flang/lib/parser/basic-parsers.h index 46e7809..f63c424 100644 --- a/flang/lib/parser/basic-parsers.h +++ b/flang/lib/parser/basic-parsers.h @@ -1187,13 +1187,11 @@ constexpr struct NextCh { using resultType = const char *; constexpr NextCh() {} std::optional Parse(ParseState *state) const { - if (state->IsAtEnd()) { - state->Say("end of file"_err_en_US); - return {}; + if (std::optional result{state->GetNextChar()}) { + return std::move(result); } - const char *at{state->GetLocation()}; - state->UncheckedAdvance(); - return {at}; + state->Say("end of file"_err_en_US); + return {}; } } nextCh; diff --git a/flang/lib/parser/grammar.h b/flang/lib/parser/grammar.h index e3a91f4..446cae0 100644 --- a/flang/lib/parser/grammar.h +++ b/flang/lib/parser/grammar.h @@ -747,11 +747,11 @@ constexpr auto exponentPart = TYPE_CONTEXT_PARSER("REAL literal constant"_en_US, construct{}( sourced( - (digitString >> "."_ch >> + (skipDigitString >> "."_ch >> !(some(letter) >> "."_ch /* don't misinterpret 1.AND. */) >> - maybe(digitString) >> maybe(exponentPart) >> ok || - "."_ch >> digitString >> maybe(exponentPart) >> ok || - digitString >> exponentPart >> ok) >> + maybe(skipDigitString) >> maybe(exponentPart) >> ok || + "."_ch >> skipDigitString >> maybe(exponentPart) >> ok || + skipDigitString >> exponentPart >> ok) >> construct{}), maybe(underscore >> kindParam))) diff --git a/flang/lib/parser/message.h b/flang/lib/parser/message.h index 583507c..9d166ec 100644 --- a/flang/lib/parser/message.h +++ b/flang/lib/parser/message.h @@ -89,6 +89,7 @@ public: Message &operator=(const Message &that) = default; Message &operator=(Message &&that) = default; + // TODO: Change these to cover ranges of provenance Message(Provenance p, MessageFixedText t, MessageContext c = nullptr) : provenance_{p}, text_{t}, context_{c}, isFatal_{t.isFatal()} {} Message(Provenance p, MessageFormattedText &&s, MessageContext c = nullptr) diff --git a/flang/lib/parser/parse-state.h b/flang/lib/parser/parse-state.h index 2ff16bd..63d98db 100644 --- a/flang/lib/parser/parse-state.h +++ b/flang/lib/parser/parse-state.h @@ -134,24 +134,24 @@ public: bool IsAtEnd() const { return p_ >= limit_; } - char UncheckedAdvance(std::size_t n = 1) { - char result{*p_}; + const char *UncheckedAdvance(std::size_t n = 1) { + const char *result{p_}; p_ += n; return result; } - std::optional GetNextChar() { + std::optional GetNextChar() { if (p_ >= limit_) { return {}; } return {UncheckedAdvance()}; } - std::optional PeekAtNextChar() { + std::optional PeekAtNextChar() { if (p_ >= limit_) { return {}; } - return {*p_}; + return {p_}; } private: diff --git a/flang/lib/parser/parsing.cc b/flang/lib/parser/parsing.cc index 2ce013f..4764823 100644 --- a/flang/lib/parser/parsing.cc +++ b/flang/lib/parser/parsing.cc @@ -57,8 +57,8 @@ void Parsing::DumpCookedChars(std::ostream &out) const { UserState userState; ParseState parseState{cooked_}; parseState.set_inFixedForm(options_.isFixedForm).set_userState(&userState); - while (std::optional ch{parseState.GetNextChar()}) { - out << *ch; + while (std::optional p{parseState.GetNextChar()}) { + out << **p; } } diff --git a/flang/lib/parser/token-parsers.h b/flang/lib/parser/token-parsers.h index 9c38cfd..39f2289 100644 --- a/flang/lib/parser/token-parsers.h +++ b/flang/lib/parser/token-parsers.h @@ -85,8 +85,8 @@ constexpr struct Space { using resultType = Success; constexpr Space() {} static std::optional Parse(ParseState *state) { - while (std::optional ch{state->PeekAtNextChar()}) { - if (*ch != ' ') { + while (std::optional p{state->PeekAtNextChar()}) { + if (**p != ' ') { break; } state->UncheckedAdvance(); @@ -110,12 +110,13 @@ constexpr struct SpaceCheck { using resultType = Success; constexpr SpaceCheck() {} static std::optional Parse(ParseState *state) { - if (std::optional ch{state->PeekAtNextChar()}) { - if (*ch == ' ') { + if (std::optional p{state->PeekAtNextChar()}) { + char ch{**p}; + if (ch == ' ') { state->UncheckedAdvance(); return space.Parse(state); } - if (IsLegalInIdentifier(*ch)) { + if (IsLegalInIdentifier(ch)) { MissingSpace(state); } } @@ -263,7 +264,7 @@ struct CharLiteralChar { ch -= '0'; for (int j = (ch > 3 ? 1 : 2); j-- > 0;) { static constexpr auto octalDigit = - CharPredicateGuard{IsOctalDigit, "expected octal digit"_err_en_US}; + CharPredicateGuard{IsOctalDigit, "expected octal digit"_en_US}; och = octalDigit.Parse(state); if (och.has_value()) { ch = 8 * ch + **och - '0'; @@ -275,7 +276,7 @@ struct CharLiteralChar { ch = 0; for (int j = 0; j++ < 2;) { static constexpr auto hexDigit = CharPredicateGuard{ - IsHexadecimalDigit, "expected hexadecimal digit"_err_en_US}; + IsHexadecimalDigit, "expected hexadecimal digit"_en_US}; och = hexDigit.Parse(state); if (och.has_value()) { ch = 16 * ch + HexadecimalDigitValue(**och); @@ -284,7 +285,7 @@ struct CharLiteralChar { } } } else { - state->Say(at, "bad escaped character"_err_en_US); + state->Say(at, "bad escaped character"_en_US); } return {Result::Escaped(ch)}; } @@ -438,6 +439,25 @@ struct DigitString { } }; +constexpr struct SkipDigitString { + using resultType = Success; + static std::optional Parse(ParseState *state) { + if (std::optional ch1{state->PeekAtNextChar()}) { + if (IsDecimalDigit(**ch1)) { + state->UncheckedAdvance(); + while (std::optional p{state->PeekAtNextChar()}) { + if (!IsDecimalDigit(**p)) { + break; + } + state->UncheckedAdvance(); + } + return {Success{}}; + } + } + return {}; + } +} skipDigitString; + // Legacy feature: Hollerith literal constants struct HollerithLiteral { using resultType = std::string; @@ -508,8 +528,8 @@ template struct SkipPast { constexpr SkipPast() {} constexpr SkipPast(const SkipPast &) {} static std::optional Parse(ParseState *state) { - while (std::optional ch{state->GetNextChar()}) { - if (*ch == goal) { + while (std::optional p{state->GetNextChar()}) { + if (**p == goal) { return {Success{}}; } } @@ -522,8 +542,8 @@ template struct SkipTo { constexpr SkipTo() {} constexpr SkipTo(const SkipTo &) {} static std::optional Parse(ParseState *state) { - while (std::optional ch{state->PeekAtNextChar()}) { - if (*ch == goal) { + while (std::optional p{state->PeekAtNextChar()}) { + if (**p == goal) { return {Success{}}; } state->UncheckedAdvance(); -- 2.7.4