[flang] Remove old character "cooking" parser combinators that handled Fortran
authorpeter klausler <pklausler@nvidia.com>
Fri, 16 Feb 2018 18:41:16 +0000 (10:41 -0800)
committerpeter klausler <pklausler@nvidia.com>
Fri, 16 Feb 2018 18:41:16 +0000 (10:41 -0800)
comments, continuations, &c. that have become obsolete with the use
of the new C++-coded prescanner module.  Clean out members from
ParseState that were used only by cookedNextChar and its sub-parsers.

Original-commit: flang-compiler/f18@41717531e5eb17dc4f090babbeb63745397d80cc
Reviewed-on: https://github.com/flang-compiler/f18/pull/11
Tree-same-pre-rewrite: false

flang/documentation/ParserCombinators.md
flang/lib/parser/basic-parsers.h
flang/lib/parser/char-parsers.h [deleted file]
flang/lib/parser/cooked-chars.h [deleted file]
flang/lib/parser/grammar.h
flang/lib/parser/parse-state.h
flang/lib/parser/token-parsers.h [moved from flang/lib/parser/cooked-tokens.h with 89% similarity]
flang/tools/f18/f18.cc
flang/tools/f18/test-type.cc

index bfb1e66..c56ddb7 100644 (file)
@@ -45,9 +45,7 @@ These objects and functions are (or return) the fundamental parsers:
 * `cut` is a trivial parser that always fails silently.
 * `guard(pred)` returns a parser that succeeds if and only if the predicate
   expression evaluates to true.
-* `rawNextChar` returns the next raw character, and fails at EOF.
-* `cookedNextChar` returns the next character after preprocessing, skipping
-  Fortran line continuations and comments; it also fails at EOF
+* `nextChar` returns the next character, and fails at EOF.
 
 ### Combinators
 These functions and operators combine existing parsers to generate new parsers.
@@ -107,26 +105,15 @@ collect the values that they return.
 These are non-advancing state inquiry and update parsers:
 
 * `getColumn` returns the 1-based column position.
-* `inCharLiteral` succeeds under `withinCharLiteral` (below).
-* `inFortran` succeeds unless in a preprocessing directive.
 * `inFixedForm` succeeds in fixed form Fortran source.
 * `setInFixedForm` sets the fixed form flag, returning its prior value.
 * `columns` returns the 1-based column number after which source is clipped.
 * `setColumns(c)` sets the column limit and returns its prior value.
 
-### Monadic Combination
-When parsing depends on the result values of earlier parses, the
-*monadic bind* combinator is available.
-Please try to avoid using it, as it makes automatic analysis of the
-grammar difficult.
-It has the syntax `p >>= f`, and it constructs a parser that matches p,
-yielding some value x on success, then matches the parser returned from
-the function call `f(x)`.
-
 ### Token Parsers
 Last, we have these basic parsers on which the actual grammar of the Fortran
 is built.  All of the following parsers consume characters acquired from
-`cookedNextChar`.
+`nextChar`.
 
 * `spaces` always succeeds after consuming any spaces or tabs
 * `digit` matches one cooked decimal digit (0-9)
@@ -138,8 +125,6 @@ is built.  All of the following parsers consume characters acquired from
   the combinator `>>` or after `/`.)
 * `parenthesized(p)` is shorthand for `"(" >> p / ")"`.
 * `bracketed(p)` is shorthand for `"[" >> p / "]"`.
-* `withinCharLiteral(p)` applies the parser p, tokenizing for
-  CHARACTER/Hollerith literals.
 * `nonEmptyListOf(p)` matches a comma-separated list of one or more
   instances of p.
 * `optionalListOf(p)` is the same thing, but can be empty, and always succeeds.
index 8b655a1..1cc26ad 100644 (file)
@@ -1179,45 +1179,20 @@ private:
 
 inline constexpr auto guard(bool truth) { return GuardParser(truth); }
 
-// rawNextChar is a parser that succeeds if the parsing state is not
+// nextChar is a parser that succeeds if the parsing state is not
 // at the end of its input, returning the next character and
 // advancing the parse when it does so.
-constexpr struct RawNextCharParser {
+constexpr struct NextCharParser {
   using resultType = char;
-  constexpr RawNextCharParser() {}
+  constexpr NextCharParser() {}
   std::optional<char> Parse(ParseState *state) const {
-    if (std::optional<char> ch{state->GetNextRawChar()}) {
-      state->Advance();
-      return ch;
+    std::optional<char> ch{state->GetNextChar()};
+    if (!ch) {
+      state->PutMessage("end of file");
     }
-    state->PutMessage("end of file");
-    return {};
-  }
-} rawNextChar;
-
-// If a is a parser, then withinCharLiteral(a) succeeds if a does so, with the
-// parsing state temporarily modified during the recognition of a to
-// signify that the parse is within quotes or Hollerith.
-template<typename PA> class WithinCharLiteral {
-public:
-  using resultType = typename PA::resultType;
-  constexpr WithinCharLiteral(const WithinCharLiteral &) = default;
-  constexpr WithinCharLiteral(const PA &parser) : parser_{parser} {}
-  std::optional<resultType> Parse(ParseState *state) const {
-    bool was{state->inCharLiteral()};
-    std::optional<resultType> result{parser_.Parse(state)};
-    state->set_inCharLiteral(was);
-    return result;
+    return ch;
   }
-
-private:
-  const PA parser_;
-};
-
-template<typename PA>
-inline constexpr auto withinCharLiteral(const PA &parser) {
-  return WithinCharLiteral<PA>(parser);
-}
+} nextChar;
 
 // If a is a parser for nonstandard usage, extension(a) is a parser that
 // is disabled if strict standard compliance is enforced, and enabled with
diff --git a/flang/lib/parser/char-parsers.h b/flang/lib/parser/char-parsers.h
deleted file mode 100644 (file)
index cb5b6d5..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-#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 {
-namespace parser {
-
-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 parser
-}  // namespace Fortran
-#endif  // FORTRAN_CHAR_PARSERS_H_
diff --git a/flang/lib/parser/cooked-chars.h b/flang/lib/parser/cooked-chars.h
deleted file mode 100644 (file)
index 4b5f88c..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-#ifndef FORTRAN_COOKED_CHARS_H_
-#define FORTRAN_COOKED_CHARS_H_
-
-// Defines the parser cookedNextChar, which supplies all of the input to
-// the next stage of parsing, viz. the tokenization parsers in cooked-tokens.h.
-// It consumes the stream of raw characters and removes Fortran comments,
-// continuation line markers, and characters that appear in the right margin
-// of fixed form source after the column limit.  It inserts spaces to
-// pad out source card images to fixed form's right margin when necessary.
-// These parsers are largely bypassed when the prescanner is used, but still
-// serve as the definition of correct character cooking, apart from
-// preprocessing and file inclusion, which are not supported here.
-
-#include "basic-parsers.h"
-#include "char-parsers.h"
-#include "idioms.h"
-#include "parse-state.h"
-#include <optional>
-
-namespace Fortran {
-namespace parser {
-
-constexpr struct FixedFormPadding {
-  using resultType = char;
-  static std::optional<char> Parse(ParseState *state) {
-    if (state->inCharLiteral() && state->inFortran() && state->inFixedForm() &&
-        state->column() <= state->columns()) {
-      if (std::optional<char> ch{state->GetNextRawChar()}) {
-        if (*ch == '\n') {
-          state->AdvanceColumnForPadding();
-          return {' '};
-        }
-      }
-    }
-    return {};
-  }
-} fixedFormPadding;
-
-static inline void IncrementSkippedNewLines(ParseState *state) {
-  state->set_skippedNewLines(state->skippedNewLines() + 1);
-}
-
-constexpr StateUpdateParser noteSkippedNewLine{IncrementSkippedNewLines};
-
-static inline bool InRightMargin(const ParseState &state) {
-  if (state.inFortran() && state.inFixedForm() &&
-      state.column() > state.columns() && !state.tabInCurrentLine()) {
-    if (std::optional<char> ch{state.GetNextRawChar()}) {
-      return *ch != '\n';
-    }
-  }
-  return false;
-}
-
-constexpr StatePredicateGuardParser inRightMargin{InRightMargin};
-
-template<int col> struct AtFixedFormColumn {
-  using resultType = Success;
-  constexpr AtFixedFormColumn() {}
-  constexpr AtFixedFormColumn(const AtFixedFormColumn &) {}
-  static std::optional<Success> Parse(ParseState *state) {
-    if (state->inFortran() && state->inFixedForm() && !state->IsAtEnd() &&
-        state->column() == col) {
-      return {Success{}};
-    }
-    return {};
-  }
-};
-
-template<int col> struct AtColumn {
-  using resultType = Success;
-  constexpr AtColumn() {}
-  constexpr AtColumn(const AtColumn &) {}
-  static std::optional<Success> Parse(ParseState *state) {
-    if (!state->IsAtEnd() && state->column() == col) {
-      return {Success{}};
-    }
-    return {};
-  }
-};
-
-static inline bool AtOldDebugLineMarker(const ParseState &state) {
-  if (state.inFortran() && state.inFixedForm() && state.column() == 1) {
-    if (std::optional<char> ch{state.GetNextRawChar()}) {
-      return toupper(*ch) == 'D';
-    }
-  }
-  return false;
-}
-
-static inline bool AtDisabledOldDebugLine(const ParseState &state) {
-  return AtOldDebugLineMarker(state) && !state.enableOldDebugLines();
-}
-
-static inline bool AtEnabledOldDebugLine(const ParseState &state) {
-  return AtOldDebugLineMarker(state) && state.enableOldDebugLines();
-}
-
-static constexpr StatePredicateGuardParser atDisabledOldDebugLine{
-    AtDisabledOldDebugLine},
-    atEnabledOldDebugLine{AtEnabledOldDebugLine};
-
-constexpr auto skipPastNewLine = SkipPast<'\n'>{} / noteSkippedNewLine;
-
-// constexpr auto rawSpace =
-//  (ExactRaw<' '>{} || ExactRaw<'\t'>{} ||
-//   atEnabledOldDebugLine >> rawNextChar) >> ok;
-constexpr struct FastRawSpaceParser {
-  using resultType = Success;
-  constexpr FastRawSpaceParser() {}
-  constexpr FastRawSpaceParser(const FastRawSpaceParser &) {}
-  static std::optional<Success> Parse(ParseState *state) {
-    if (std::optional<char> ch{state->GetNextRawChar()}) {
-      if (*ch == ' ' || *ch == '\t' ||
-          (toupper(*ch) == 'D' && state->column() == 1 &&
-              state->enableOldDebugLines() && state->inFortran() &&
-              state->inFixedForm())) {
-        state->Advance();
-        return {Success{}};
-      }
-    }
-    return {};
-  }
-} rawSpace;
-
-constexpr auto skipAnyRawSpaces = skipManyFast(rawSpace);
-
-constexpr auto commentBang =
-    !inCharLiteral >> !AtFixedFormColumn<6>{} >> ExactRaw<'!'>{} >> ok;
-
-constexpr auto fixedComment = AtFixedFormColumn<1>{} >>
-    ((ExactRaw<'*'>{} || ExactRaw<'C'>{} || ExactRaw<'c'>{}) >> ok ||
-        atDisabledOldDebugLine ||
-        extension(ExactRaw<'%'>{} /* VAX %list, %eject, &c. */) >> ok);
-
-constexpr auto comment =
-    (skipAnyRawSpaces >> (commentBang || inRightMargin) || fixedComment) >>
-    skipPastNewLine;
-
-constexpr auto blankLine = skipAnyRawSpaces >> eoln >> ok;
-
-inline bool InFortran(const ParseState &state) { return state.inFortran(); }
-
-constexpr StatePredicateGuardParser inFortran{InFortran};
-
-inline bool FixedFormFortran(const ParseState &state) {
-  return state.inFortran() && state.inFixedForm();
-}
-
-constexpr StatePredicateGuardParser fixedFormFortran{FixedFormFortran};
-
-inline bool FreeFormFortran(const ParseState &state) {
-  return state.inFortran() && !state.inFixedForm();
-}
-
-constexpr StatePredicateGuardParser freeFormFortran{FreeFormFortran};
-
-constexpr auto lineEnd = comment || blankLine;
-constexpr auto skippedLineEnd = lineEnd / noteSkippedNewLine;
-constexpr auto someSkippedLineEnds = skippedLineEnd >> skipMany(skippedLineEnd);
-
-constexpr auto fixedFormContinuation = fixedFormFortran >>
-    someSkippedLineEnds >>
-    (extension(AtColumn<1>{} >>
-         (ExactRaw<'&'>{} ||  // extension: & in column 1
-             (ExactRaw<'\t'>{} >>  // VAX Fortran: tab and then 1-9
-                 ExactRawRange<'1', '9'>{}))) ||
-        (skipAnyRawSpaces >> AtColumn<6>{} >> AnyCharExcept<'0'>{})) >>
-    ok;
-
-constexpr auto freeFormContinuation = freeFormFortran >>
-    ((ExactRaw<'&'>{} >> blankLine >> skipMany(skippedLineEnd) >>
-         skipAnyRawSpaces >> ExactRaw<'&'>{} >> ok) ||
-        (ExactRaw<'&'>{} >> !inCharLiteral >> someSkippedLineEnds >>
-            maybe(skipAnyRawSpaces >> ExactRaw<'&'>{}) >> ok) ||
-        // PGI-only extension: don't need '&' on initial line if it's on later
-        // one
-        extension(eoln >> skipMany(skippedLineEnd) >> skipAnyRawSpaces >>
-            ExactRaw<'&'>{} >> ok));
-
-constexpr auto skippable = freeFormContinuation ||
-    fixedFormFortran >> (fixedFormContinuation || !inCharLiteral >> rawSpace ||
-                            AtColumn<6>{} >> ExactRaw<'0'>{} >> ok);
-
-char toLower(char &&ch) { return tolower(ch); }
-
-// TODO: skip \\ \n in C mode, increment skipped newline count;
-// drain skipped newlines.
-
-constexpr auto slowCookedNextChar = fixedFormPadding ||
-    skipMany(skippable) >>
-        (inCharLiteral >> rawNextChar || lineEnd >> pure('\n') ||
-            rawSpace >> skipAnyRawSpaces >> pure(' ') ||
-            // TODO: detect and report non-digit in fixed form label field
-            inFortran >> applyFunction(toLower, rawNextChar) || rawNextChar);
-
-constexpr struct CookedChar {
-  using resultType = char;
-  static std::optional<char> Parse(ParseState *state) {
-    if (state->prescanned()) {
-      return rawNextChar.Parse(state);
-    }
-    return slowCookedNextChar.Parse(state);
-  }
-} cookedNextChar;
-
-static inline bool ConsumedAllInput(const ParseState &state) {
-  return state.IsAtEnd();
-}
-
-constexpr StatePredicateGuardParser consumedAllInput{ConsumedAllInput};
-}  // namespace parser
-}  // namespace Fortran
-#endif  // FORTRAN_COOKED_CHARS_H_
index b15b693..3317ef3 100644 (file)
@@ -2,14 +2,13 @@
 #define FORTRAN_GRAMMAR_H_
 
 // Top-level grammar specification for Fortran.  These parsers drive
-// tokenizing and raw character parsers (cooked-tokens.h, cooked-chars.h)
-// to recognize the productions of Fortran and to construct a parse tree.
+// the tokenization parsers in cooked-tokens.h to consume characters,
+// recognize the productions of Fortran, and to construct a parse tree.
 // See parser-combinators.txt for documentation on the parser combinator
 // library used here to implement an LL recursive descent recognizer.
 
 #include "basic-parsers.h"
-#include "cooked-chars.h"
-#include "cooked-tokens.h"
+#include "token-parsers.h"
 #include "format-specification.h"
 #include "parse-tree.h"
 #include "user-state.h"
@@ -540,7 +539,7 @@ constexpr auto executableConstruct =
 constexpr auto executionPartErrorRecovery = skipMany("\n"_tok) >>
     maybe(label) >> !"END"_tok >> !"ELSE"_tok >> !"CONTAINS"_tok >>
     !"CASE"_tok >> !"TYPE IS"_tok >> !"CLASS"_tok >>
-    !"RANK"_tok >> skipPastNewLine >> construct<ErrorRecovery>{};
+    !"RANK"_tok >> SkipPast<'\n'>{} >> construct<ErrorRecovery>{};
 
 // R510 execution-part-construct ->
 //        executable-construct | format-stmt | entry-stmt | data-stmt
index 3f49da9..2965bef 100644 (file)
@@ -30,33 +30,25 @@ public:
   ParseState(const ParseState &that)
     : cooked_{that.cooked_}, p_{that.p_}, limit_{that.limit_},
       column_{that.column_}, messages_{*that.cooked_.allSources()},
-      userState_{that.userState_}, inCharLiteral_{that.inCharLiteral_},
-      inFortran_{that.inFortran_}, inFixedForm_{that.inFixedForm_},
-      enableOldDebugLines_{that.enableOldDebugLines_}, columns_{that.columns_},
+      userState_{that.userState_}, inFixedForm_{that.inFixedForm_},
       enableBackslashEscapesInCharLiterals_{
           that.enableBackslashEscapesInCharLiterals_},
       strictConformance_{that.strictConformance_},
       warnOnNonstandardUsage_{that.warnOnNonstandardUsage_},
       warnOnDeprecatedUsage_{that.warnOnDeprecatedUsage_},
-      skippedNewLines_{that.skippedNewLines_},
-      tabInCurrentLine_{that.tabInCurrentLine_},
-      anyErrorRecovery_{that.anyErrorRecovery_}, prescanned_{that.prescanned_} {
+      anyErrorRecovery_{that.anyErrorRecovery_} {
   }
   ParseState(ParseState &&that)
     : cooked_{that.cooked_}, p_{that.p_}, limit_{that.limit_},
       column_{that.column_}, messages_{std::move(that.messages_)},
       context_{std::move(that.context_)}, userState_{that.userState_},
-      inCharLiteral_{that.inCharLiteral_}, inFortran_{that.inFortran_},
       inFixedForm_{that.inFixedForm_},
-      enableOldDebugLines_{that.enableOldDebugLines_}, columns_{that.columns_},
       enableBackslashEscapesInCharLiterals_{
           that.enableBackslashEscapesInCharLiterals_},
       strictConformance_{that.strictConformance_},
       warnOnNonstandardUsage_{that.warnOnNonstandardUsage_},
       warnOnDeprecatedUsage_{that.warnOnDeprecatedUsage_},
-      skippedNewLines_{that.skippedNewLines_},
-      tabInCurrentLine_{that.tabInCurrentLine_},
-      anyErrorRecovery_{that.anyErrorRecovery_}, prescanned_{that.prescanned_} {
+      anyErrorRecovery_{that.anyErrorRecovery_} {
   }
   ParseState &operator=(ParseState &&that) {
     swap(that);
@@ -87,36 +79,12 @@ public:
     return *this;
   }
 
-  bool inCharLiteral() const { return inCharLiteral_; }
-  ParseState &set_inCharLiteral(bool yes) {
-    inCharLiteral_ = yes;
-    return *this;
-  }
-
-  bool inFortran() const { return inFortran_; }
-  ParseState &set_inFortran(bool yes) {
-    inFortran_ = yes;
-    return *this;
-  }
-
   bool inFixedForm() const { return inFixedForm_; }
   ParseState &set_inFixedForm(bool yes) {
     inFixedForm_ = yes;
     return *this;
   }
 
-  bool enableOldDebugLines() const { return enableOldDebugLines_; }
-  ParseState &set_enableOldDebugLines(bool yes) {
-    enableOldDebugLines_ = yes;
-    return *this;
-  }
-
-  int columns() const { return columns_; }
-  ParseState &set_columns(int cols) {
-    columns_ = cols;
-    return *this;
-  }
-
   bool enableBackslashEscapesInCharLiterals() const {
     return enableBackslashEscapesInCharLiterals_;
   }
@@ -143,13 +111,6 @@ public:
     return *this;
   }
 
-  int skippedNewLines() const { return skippedNewLines_; }
-  void set_skippedNewLines(int n) { skippedNewLines_ = n; }
-
-  bool prescanned() const { return prescanned_; }  // TODO: always true, remove
-
-  bool tabInCurrentLine() const { return tabInCurrentLine_; }
-
   const char *GetLocation() const { return p_; }
   Provenance GetProvenance(const char *at) const {
     return cooked_.GetProvenance(at).LocalOffsetToProvenance(0);
@@ -197,29 +158,18 @@ public:
 
   bool IsAtEnd() const { return p_ >= limit_; }
 
-  std::optional<char> GetNextRawChar() const {
-    if (p_ < limit_) {
-      return {*p_};
+  std::optional<char> GetNextChar() {
+    if (p_ >= limit_) {
+      return {};
     }
-    return {};
-  }
-
-  void Advance() {
-    CHECK(p_ < limit_);
-    if (*p_ == '\n') {
+    char ch{*p_++};
+    ++column_;
+    if (ch == '\n') {
       column_ = 1;
-      tabInCurrentLine_ = false;
-    } else if (*p_ == '\t') {
-      column_ = ((column_ + 7) & -8) + 1;
-      tabInCurrentLine_ = true;
-    } else {
-      ++column_;
     }
-    ++p_;
+    return {ch};
   }
 
-  void AdvanceColumnForPadding() { ++column_; }
-
 private:
   // Text remaining to be parsed
   const CookedSource &cooked_;
@@ -232,19 +182,12 @@ private:
 
   UserState *userState_{nullptr};
 
-  bool inCharLiteral_{false};
-  bool inFortran_{true};
   bool inFixedForm_{false};
-  bool enableOldDebugLines_{false};
-  int columns_{72};
   bool enableBackslashEscapesInCharLiterals_{true};
   bool strictConformance_{false};
   bool warnOnNonstandardUsage_{false};
   bool warnOnDeprecatedUsage_{false};
-  int skippedNewLines_{0};
-  bool tabInCurrentLine_{false};
   bool anyErrorRecovery_{false};
-  bool prescanned_{true};
   // NOTE: Any additions or modifications to these data members must also be
   // reflected in the copy and move constructors defined at the top of this
   // class definition!
similarity index 89%
rename from flang/lib/parser/cooked-tokens.h
rename to flang/lib/parser/token-parsers.h
index b358a15..b6e3e43 100644 (file)
@@ -1,12 +1,10 @@
-#ifndef FORTRAN_COOKED_TOKENS_H_
-#define FORTRAN_COOKED_TOKENS_H_
+#ifndef FORTRAN_TOKEN_PARSERS_H_
+#define FORTRAN_TOKEN_PARSERS_H_
 
 // These parsers are driven by the Fortran grammar (grammar.h) to consume
-// the cooked character stream from cookedNextChar (cooked-chars.h) and
-// partition it into a context-sensitive token stream.
+// the prescanned character stream and recognize context-sensitive tokens.
 
 #include "basic-parsers.h"
-#include "cooked-chars.h"
 #include "idioms.h"
 #include "provenance.h"
 #include <cctype>
@@ -29,7 +27,7 @@ public:
     : predicate_{f}, message_{msg} {}
   std::optional<char> Parse(ParseState *state) const {
     auto at = state->GetLocation();
-    if (std::optional<char> result{cookedNextChar.Parse(state)}) {
+    if (std::optional<char> result{nextChar.Parse(state)}) {
       if (predicate_(*result)) {
         return result;
       }
@@ -68,7 +66,7 @@ public:
   constexpr CharMatch() {}
   static std::optional<char> Parse(ParseState *state) {
     auto at = state->GetLocation();
-    std::optional<char> result{cookedNextChar.Parse(state)};
+    std::optional<char> result{nextChar.Parse(state)};
     if (result && *result != good) {
       result.reset();
     }
@@ -83,7 +81,7 @@ constexpr struct Space {
   using resultType = Success;
   constexpr Space() {}
   static std::optional<Success> Parse(ParseState *state) {
-    std::optional<char> ch{cookedNextChar.Parse(state)};
+    std::optional<char> ch{nextChar.Parse(state)};
     if (ch) {
       if (ch == ' ' || ch == '\t') {
         return {Success{}};
@@ -116,13 +114,13 @@ public:
           continue;  // redundant; ignore
         }
       }
-      if (!ch && !(ch = cookedNextChar.Parse(state))) {
+      if (!ch && !(ch = nextChar.Parse(state))) {
         return {};
       }
       if (spaceSkipping) {
         // medial space: 0 or more spaces/tabs accepted, none required
         while (*ch == ' ' || *ch == '\t') {
-          if (!(ch = cookedNextChar.Parse(state))) {
+          if (!(ch = nextChar.Parse(state))) {
             return {};
           }
         }
@@ -191,7 +189,7 @@ struct CharLiteralChar {
   using resultType = Result;
   static std::optional<Result> Parse(ParseState *state) {
     auto at = state->GetLocation();
-    std::optional<char> och{cookedNextChar.Parse(state)};
+    std::optional<char> och{nextChar.Parse(state)};
     if (!och.has_value()) {
       return {};
     }
@@ -203,7 +201,7 @@ struct CharLiteralChar {
     if (ch != '\\' || !state->enableBackslashEscapesInCharLiterals()) {
       return {Result::Bare(ch)};
     }
-    if (!(och = cookedNextChar.Parse(state)).has_value()) {
+    if (!(och = nextChar.Parse(state)).has_value()) {
       return {};
     }
     switch ((ch = *och)) {
@@ -249,13 +247,11 @@ template<char quote> struct CharLiteral {
   using resultType = std::string;
   static std::optional<std::string> Parse(ParseState *state) {
     std::string str;
-    CHECK(!state->inCharLiteral());
     static constexpr auto nextch = attempt(CharLiteralChar{});
     while (std::optional<CharLiteralChar::Result> ch{nextch.Parse(state)}) {
       if (ch->ch == quote && !ch->wasEscaped) {
         static constexpr auto doubled = attempt(CharMatch<quote>{});
         if (!doubled.Parse(state).has_value()) {
-          state->set_inCharLiteral(false);
           return {str};
         }
       }
@@ -286,14 +282,14 @@ struct BOZLiteral {
       return {};
     }
 
-    auto ch = cookedNextChar.Parse(state);
+    auto ch = nextChar.Parse(state);
     if (!ch) {
       return {};
     }
     if (toupper(*ch) == 'X' && state->strictConformance()) {
       return {};
     }
-    if (baseChar(*ch) && !(ch = cookedNextChar.Parse(state))) {
+    if (baseChar(*ch) && !(ch = nextChar.Parse(state))) {
       return {};
     }
 
@@ -305,7 +301,7 @@ struct BOZLiteral {
     auto at = state->GetLocation();
     std::string content;
     while (true) {
-      if (!(ch = cookedNextChar.Parse(state))) {
+      if (!(ch = nextChar.Parse(state))) {
         return {};
       }
       if (*ch == quote) {
@@ -319,7 +315,7 @@ struct BOZLiteral {
 
     if (!shift && !state->strictConformance()) {
       // extension: base allowed to appear as suffix
-      if (!(ch = cookedNextChar.Parse(state)) || !baseChar(*ch)) {
+      if (!(ch = nextChar.Parse(state)) || !baseChar(*ch)) {
         return {};
       }
     }
@@ -395,22 +391,44 @@ struct HollerithLiteral {
       return {};
     }
     std::string content;
-    CHECK(!state->inCharLiteral());
-    state->set_inCharLiteral(true);
     for (auto j = *charCount; j-- > 0;) {
-      std::optional<char> ch{cookedNextChar.Parse(state)};
+      std::optional<char> ch{nextChar.Parse(state)};
       if (!ch || !isprint(*ch)) {
         state->PutMessage(at, "insufficient or bad characters in Hollerith");
-        state->set_inCharLiteral(false);
         return {};
       }
       content += *ch;
     }
-    state->set_inCharLiteral(false);
     return {content};
   }
 };
 
+struct ConsumedAllInputParser {
+  using resultType = Success;
+  constexpr ConsumedAllInputParser() {}
+  static std::optional<Success> Parse(ParseState *state) {
+    if (state->IsAtEnd()) {
+      return {Success{}};
+    }
+    return {};
+  }
+} consumedAllInput;
+
+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->GetNextChar()}) {
+      if (*ch == goal) {
+        return {Success{}};
+      }
+    }
+    return {};
+  }
+};
+
 // A common idiom in the Fortran grammar is an optional item (usually
 // a nonempty comma-separated list) that, if present, must follow a comma
 // and precede a doubled colon.  When the item is absent, the comma must
@@ -423,4 +441,4 @@ template<typename PA> inline constexpr auto optionalBeforeColons(const PA &p) {
 }
 }  // namespace parser
 }  // namespace Fortran
-#endif  // FORTRAN_COOKED_TOKENS_H_
+#endif  // FORTRAN_TOKEN_PARSERS_H_
index 1d7dc07..d8b440a 100644 (file)
@@ -1,8 +1,5 @@
 // Temporary Fortran front end driver main program for development scaffolding.
 
-#include "../../lib/parser/basic-parsers.h"
-#include "../../lib/parser/char-buffer.h"
-#include "../../lib/parser/cooked-chars.h"
 #include "../../lib/parser/grammar.h"
 #include "../../lib/parser/idioms.h"
 #include "../../lib/parser/message.h"
@@ -151,13 +148,10 @@ int main(int argc, char *const argv[]) {
   state.set_inFixedForm(fixedForm)
       .set_enableBackslashEscapesInCharLiterals(backslashEscapes)
       .set_strictConformance(standard)
-      .set_columns(columns)
-      .set_enableOldDebugLines(enableOldDebugLines)
       .set_userState(&ustate);
 
   if (dumpCookedChars) {
-    while (std::optional<char> och{
-        Fortran::parser::cookedNextChar.Parse(&state)}) {
+    while (std::optional<char> och{state.GetNextChar()}) {
       std::cout << *och;
     }
     return 0;
index c41047e..029fc33 100644 (file)
@@ -1,11 +1,3 @@
-#include <cstdlib>
-#include <iostream>
-#include <list>
-#include <optional>
-#include <sstream>
-#include <stddef.h>
-#include <string>
-
 #include "../../lib/parser/grammar.h"
 #include "../../lib/parser/idioms.h"
 #include "../../lib/parser/indirection.h"
 #include "../../lib/parser/user-state.h"
 #include "../../lib/semantics/attr.h"
 #include "../../lib/semantics/type.h"
+#include <cstdlib>
+#include <iostream>
+#include <list>
+#include <optional>
+#include <sstream>
+#include <string>
+#include <stddef.h>
 
 using namespace Fortran;
 using namespace parser;