[flang] Add parse-state.h.
authorpeter klausler <pklausler@nvidia.com>
Tue, 30 Jan 2018 19:51:59 +0000 (11:51 -0800)
committerpeter klausler <pklausler@nvidia.com>
Tue, 30 Jan 2018 19:51:59 +0000 (11:51 -0800)
Original-commit: flang-compiler/f18@357c9f27955fb3051e85d12720a9271fa8de1b85

flang/parse-state.h [new file with mode: 0644]

diff --git a/flang/parse-state.h b/flang/parse-state.h
new file mode 100644 (file)
index 0000000..dbb4e0f
--- /dev/null
@@ -0,0 +1,236 @@
+#ifndef FORTRAN_PARSE_STATE_H_
+#define FORTRAN_PARSE_STATE_H_
+
+// Defines the ParseState type used as the argument for every parser's
+// Parse member or static function.  Tracks position, context, accumulated
+// messages, and an arbitrary UserState instance for parsing attempts.
+// Must be efficient to duplicate and assign for backtracking and recovery
+// during parsing!
+
+#include "idioms.h"
+#include "message.h"
+#include "position.h"
+#include <cstring>
+#include <list>
+#include <memory>
+#include <optional>
+#include <utility>
+
+namespace Fortran {
+
+class UserState;
+
+class ParseState {
+ public:
+  ParseState() {}
+  ParseState(const char *str) : p_{str}, remaining_{std::strlen(str)} {}
+  ParseState(const char *str, size_t bytes) : p_{str}, remaining_{bytes} {}
+  ParseState(const ParseState &that)
+    : p_{that.p_}, remaining_{that.remaining_}, position_{that.position_},
+      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_} {}
+  ParseState(ParseState &&that)
+    : p_{that.p_}, remaining_{that.remaining_}, position_{that.position_},
+      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_} {}
+  ParseState &operator=(ParseState &&that) {
+    swap(that);
+    return *this;
+  }
+
+  void swap(ParseState &that) {
+    constexpr size_t bytes{sizeof *this};
+    char buffer[bytes];
+    std::memcpy(buffer, this, bytes);
+    std::memcpy(this, &that, bytes);
+    std::memcpy(&that, buffer, bytes);
+  }
+
+  Position position() const { return position_; }
+
+  bool anyErrorRecovery() const { return anyErrorRecovery_; }
+  void set_anyErrorRecovery() { anyErrorRecovery_ = true; }
+
+  UserState *userState() const { return userState_; }
+  void set_userState(UserState *u) { userState_ = u; }
+
+  Messages *messages() { return &messages_; }
+
+  MessageContext context() const { return context_; }
+  MessageContext set_context(MessageContext c) {
+    MessageContext was{context_};
+    context_ = c;
+    return was;
+  }
+
+  void PushContext(const std::string &str) {
+    context_ = std::make_shared<Message>(position_, str, context_);
+  }
+  void PushContext(std::string &&str) {
+    context_ = std::make_shared<Message>(position_, std::move(str), context_);
+  }
+  void PushContext(const char *str) {
+    context_ = std::make_shared<Message>(position_, str, context_);
+  }
+
+  void PopContext() {
+    if (context_) {
+      context_ = context_->context();
+    }
+  }
+
+  bool inCharLiteral() const { return inCharLiteral_; }
+  bool set_inCharLiteral(bool yes) {
+    bool was{inCharLiteral_};
+    inCharLiteral_ = yes;
+    return was;
+  }
+
+  bool inFortran() const { return inFortran_; }
+  bool set_inFortran(bool yes) {
+    bool was{inFortran_};
+    inFortran_ = yes;
+    return was;
+  }
+
+  bool inFixedForm() const { return inFixedForm_; }
+  bool set_inFixedForm(bool yes) {
+    bool was{inFixedForm_};
+    inFixedForm_ = yes;
+    return was;
+  }
+
+  bool enableOldDebugLines() const { return enableOldDebugLines_; }
+  bool set_enableOldDebugLines(bool yes) {
+    bool was{enableOldDebugLines_};
+    enableOldDebugLines_ = yes;
+    return was;
+  }
+
+  int columns() const { return columns_; }
+  int set_columns(int cols) {
+    int was{columns_};
+    columns_ = cols;
+    return was;
+  }
+
+  bool enableBackslashEscapesInCharLiterals() const {
+    return enableBackslashEscapesInCharLiterals_;
+  }
+  bool set_enableBackslashEscapesInCharLiterals(bool yes) {
+    bool was{enableBackslashEscapesInCharLiterals_};
+    enableBackslashEscapesInCharLiterals_ = yes;
+    return was;
+  }
+
+  bool strictConformance() const { return strictConformance_; }
+  bool set_strictConformance(bool yes) {
+    bool was{strictConformance_};
+    strictConformance_ = yes;
+    return was;
+  }
+
+  bool warnOnNonstandardUsage() const { return warnOnNonstandardUsage_; }
+  bool set_warnOnNonstandardUsage(bool yes) {
+    bool was{warnOnNonstandardUsage_};
+    warnOnNonstandardUsage_ = yes;
+    return was;
+  }
+
+  bool warnOnDeprecatedUsage() const { return warnOnDeprecatedUsage_; }
+  bool set_warnOnDeprecatedUsage(bool yes) {
+    bool was{warnOnDeprecatedUsage_};
+    warnOnDeprecatedUsage_ = yes;
+    return was;
+  }
+
+  int skippedNewLines() const { return skippedNewLines_; }
+  void set_skippedNewLines(int n) { skippedNewLines_ = n; }
+
+  bool prescanned() const { return prescanned_; }
+  void set_prescanned(bool yes) { prescanned_ = yes; }
+
+  bool tabInCurrentLine() const { return tabInCurrentLine_; }
+
+  bool IsAtEnd() const { return remaining_ == 0; }
+
+  std::optional<char> GetNextRawChar() const {
+    if (remaining_ > 0) {
+      return {*p_};
+    }
+    return {};
+  }
+
+  void Advance() {
+    CHECK(remaining_ > 0);
+    --remaining_;
+    if (*p_ == '\n') {
+      position_.AdvanceLine();
+      tabInCurrentLine_ = false;
+    } else if (*p_ == '\t') {
+      position_.TabAdvanceColumn();
+      tabInCurrentLine_ = true;
+    } else {
+      position_.AdvanceColumn();
+    }
+    ++p_;
+  }
+
+  void AdvancePositionForPadding() {
+    position_.AdvanceColumn();
+  }
+
+ private:
+  // Text remaining to be parsed
+  const char *p_{nullptr};
+  size_t remaining_{0};
+  Position position_;
+
+  // Accumulated messages and current nested context.
+  Messages messages_;
+  MessageContext context_;
+
+  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_{false};
+  // 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!
+};
+}  // namespace Fortran
+#endif  // FORTRAN_PARSE_STATE_H_